WonderTools.JsonSectionReader 1.0.2

A tool designed to facilitate data managment in unit testing.
The tool makes JSON data organized in embedded resource easy to access.
It provides numberous ways to extract a section of data, and deserialize data.

Install-Package WonderTools.JsonSectionReader -Version 1.0.2
dotnet add package WonderTools.JsonSectionReader --version 1.0.2
<PackageReference Include="WonderTools.JsonSectionReader" Version="1.0.2" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add WonderTools.JsonSectionReader --version 1.0.2
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

JsonSectionReader - A tool to manage data in unit testing

Opinions that shaped tool

While unit testing, the amount of test data could become voluminious and could easily make the test code less readable. Having the data separated from code imporves the readability of the tests in my opinion. Yes... This is an opinionated tool, and the opinions that shape this tool are listed below.

1. Test data must be separated from test code

While unit testing, the test data could be huge and when coded with the test cases, it makes the test case less readable. Having the test data separated makes the test data and test code more readable. The tool facilitates the storing the test data in a separate file.

2. Test data must be readable and easy to modify

The test data has lot of information about the tests, and it's really important for this to be readable and easy to modify. The tool facilitates this by having the test data is a json file.

3. Test data must be easily accessbile to tests

The test data must be easily accessible from the test case. Having the test data packaged in another entity would make such as a file or data base would increase the probability of errors such as "File not found", "Invalid Connection String", etc... To make the unit testing more reliable the test data and test code has to be packaged together, and test data must be quickly accessible from test code. The tool facilites this by letting your test data be stored in the same library as embedded resource.

Features of the tool

  1. Reads full or sections of JSON file
  2. Reads JSON file stored as embedded resource.
  3. Make deserializion of JSON to .Net objects easy
  4. Capable of reading various encoding formats such as UTF8, UTF32, etc...
  5. Supports for data in other languages (Non-ASCII characters)
  6. Supports tabular representation of data (similar to data from database)

Steps to use the tool

  1. Add reference to the nuget package "WonderTools.JsonSectionReader"
  2. Add a json file to your project say "TestData.json"
  3. Make this json file as an embedded resource.
  4. Add the json data that you would like it to be available
  5. Call the JsonSectionReader methods to get a section of the data and to deserialize it. (Explained with examples below)
  6. The examples shown below are available in the github repository https://github.com/WonderTools/JsonSectionReaderUsage

Example

1. Example1Sectioning

Data

Example1Sectioning.json

{
  "name": "john",
  "age" : 32 
}

Code
  JSectionReader.Section("Example1Sectioning.json").GetSection("name").GetObject<string>();
  JSectionReader.Section("Example1Sectioning.json", Encoding.Default, "name").GetObject<string>();
  new JSectionReader().Read("Example1Sectioning.json", Encoding.Default, "name").GetObject<string>();
Remarks

All of the above lines return string "john".

2. Example2Sectioning

Data

Example2Sectioning.json

{
  "employees": [
    {
      "name": "philip",
      "age": 28
    },
    {
      "name": "richard",
      "age": 31
    }
  ] 
}
Code
  JSectionReader.Section("Example2Sectioning.json").GetSection("employees", 1, "name").GetObject<string>();
Remarks

The statement return string "richard"

3. Example3Encoding

Data

Example3Encoding.json

{
  "words" : [ "good", "bad", "Mädchen" ]
}
Code
    JSectionReader.Section("Example3Encoding.json").GetSection("words", 2).GetObject<string>();
Remarks
  1. The encoding of the file is set to UTF-8 (using Notepad++)
  2. The statement return the string "Mädchen"

4. Example4FileDiscovery

Data

JsonSectionReaderUsage.Example4FileDiscovery.Foo.Example4FileDiscovery.json

{
  "animal": "lion"
}

JsonSectionReaderUsage.Example4FileDiscovery.Boo.Example4FileDiscovery.json

{
  "animal" :  "elephant" 
}
Code
    JSectionReader
        .Section("JsonSectionReaderUsage.Example4FileDiscovery.Boo.Example4FileDiscovery.json")
        .GetSection("animal").GetObject<string>();
    JSectionReader
        .Section("Example4FileDiscovery.Boo.Example4FileDiscovery.json")
        .GetSection("animal").GetObject<string>();
    JSectionReader
        .Section("Boo.Example4FileDiscovery.json")
        .GetSection("animal").GetObject<string>();
Remark
  1. There are two embedded resources named Example4FileDiscovery.json, so specifing file name as "Example4FileDiscovery.json" will be ambigious and would result in an exception.
  2. The file named has to be more specifically mentioned to avoid ambigiouty.
  3. The valid names for identifying the file are
    • JsonSectionReaderUsage.Example4FileDiscovery.Boo.Example4FileDiscovery.json
    • Example4FileDiscovery.Boo.Example4FileDiscovery.json
    • Boo.Example4FileDiscovery.json
  4. All of the above c sharp statements return the string "elephant"

5. Example5ReadingObject

Data

Example5ReadingObject.json

{
  "person" : {
    "name": "richard",
    "age" :  22
  }
}
Code
JSectionReader.Section("Example5ReadingObject.json").GetSection("person").GetObject<Person>();
Remark
  1. The statement returns a Person object with name as "richard" and Age as 22.

6. Example6ReadingList

Data

Example6ReadingList.json

{
  "numbers" : [5,4,3,2,1] 
}
Code
JSectionReader.Section("Example6ReadingList.json").GetSection("numbers").GetObject<List<int>>();
Remark
  1. The statment returns a List<int> with 5, 4, 3, 2, 1 in it.

7. Example7ReadingAsJson

Data

Example7ReadingAsJson.json

{
  "employees": [
    {
      "name": "John",
      "id": 31432
    },
    {
      "name": "Nash",
      "id": 31433
    }
  ] 
}
Code
new JSectionReader().Read("Example7ReadingAsJson.json").GetSection("employees" , 1).GetJson();
Remark
  1. The statement returns a string {"name":"Nash","id":31433}

8. Example8ListOfList

Reading a table as list of list of objects

Data

Example8ListOfList.json

{
  "data": [
    [ 1, "Monday", "Morning" ],
    [ 2, "Monday", "Afternoon" ],
    [ 3, "Tuesday", "Morning" ],
    [ 4, "Tuesday", "Afternoon" ]
  ] 
}
Code
    new JSectionReader().Read("Example8ListOfList.json").GetSection("data")
        .GetTable(typeof(int), typeof(string), typeof(string))
Remark
    new List<List<object>>()
    {
        new List<object>() {1, "Monday", "Morning"},
        new List<object>() {2, "Monday", "Afternoon"},
        new List<object>() {3, "Tuesday", "Morning"},
        new List<object>() {4, "Tuesday", "Afternoon"},
    };

The statement returns a List<List<object>> as shown above

9. Example9ListOfObject

Reading a table as list of user defined objects

Data

Example9ListOfObject.json

{
  "data": [
    [ 2432, "John", 32 ],
    [ 2222, "Nash", 33 ],
    [ 3421, "Peter", 33 ]
  ] 
}

Code
    new JSectionReader().Read("Example9ListOfObject.json").GetSection("data")
        .GetTableAsObjectList<Employee, int, string, int>(
                (id, name, age) => new Employee()
                {
                    Id = id,
                    Name = name,
                    Age = age,
                });
Remark
  new List<Employee>()
    {
        new Employee(){Id =2432,Name ="John", Age = 32},
        new Employee(){Id =2222,Name ="Nash", Age = 33},
        new Employee(){Id =3421,Name ="Peter", Age = 33},
    };

The statement returns a list of employees as shown above

JsonSectionReader - A tool to manage data in unit testing

Opinions that shaped tool

While unit testing, the amount of test data could become voluminious and could easily make the test code less readable. Having the data separated from code imporves the readability of the tests in my opinion. Yes... This is an opinionated tool, and the opinions that shape this tool are listed below.

1. Test data must be separated from test code

While unit testing, the test data could be huge and when coded with the test cases, it makes the test case less readable. Having the test data separated makes the test data and test code more readable. The tool facilitates the storing the test data in a separate file.

2. Test data must be readable and easy to modify

The test data has lot of information about the tests, and it's really important for this to be readable and easy to modify. The tool facilitates this by having the test data is a json file.

3. Test data must be easily accessbile to tests

The test data must be easily accessible from the test case. Having the test data packaged in another entity would make such as a file or data base would increase the probability of errors such as "File not found", "Invalid Connection String", etc... To make the unit testing more reliable the test data and test code has to be packaged together, and test data must be quickly accessible from test code. The tool facilites this by letting your test data be stored in the same library as embedded resource.

Features of the tool

  1. Reads full or sections of JSON file
  2. Reads JSON file stored as embedded resource.
  3. Make deserializion of JSON to .Net objects easy
  4. Capable of reading various encoding formats such as UTF8, UTF32, etc...
  5. Supports for data in other languages (Non-ASCII characters)
  6. Supports tabular representation of data (similar to data from database)

Steps to use the tool

  1. Add reference to the nuget package "WonderTools.JsonSectionReader"
  2. Add a json file to your project say "TestData.json"
  3. Make this json file as an embedded resource.
  4. Add the json data that you would like it to be available
  5. Call the JsonSectionReader methods to get a section of the data and to deserialize it. (Explained with examples below)
  6. The examples shown below are available in the github repository https://github.com/WonderTools/JsonSectionReaderUsage

Example

1. Example1Sectioning

Data

Example1Sectioning.json

{
  "name": "john",
  "age" : 32 
}

Code
  JSectionReader.Section("Example1Sectioning.json").GetSection("name").GetObject<string>();
  JSectionReader.Section("Example1Sectioning.json", Encoding.Default, "name").GetObject<string>();
  new JSectionReader().Read("Example1Sectioning.json", Encoding.Default, "name").GetObject<string>();
Remarks

All of the above lines return string "john".

2. Example2Sectioning

Data

Example2Sectioning.json

{
  "employees": [
    {
      "name": "philip",
      "age": 28
    },
    {
      "name": "richard",
      "age": 31
    }
  ] 
}
Code
  JSectionReader.Section("Example2Sectioning.json").GetSection("employees", 1, "name").GetObject<string>();
Remarks

The statement return string "richard"

3. Example3Encoding

Data

Example3Encoding.json

{
  "words" : [ "good", "bad", "Mädchen" ]
}
Code
    JSectionReader.Section("Example3Encoding.json").GetSection("words", 2).GetObject<string>();
Remarks
  1. The encoding of the file is set to UTF-8 (using Notepad++)
  2. The statement return the string "Mädchen"

4. Example4FileDiscovery

Data

JsonSectionReaderUsage.Example4FileDiscovery.Foo.Example4FileDiscovery.json

{
  "animal": "lion"
}

JsonSectionReaderUsage.Example4FileDiscovery.Boo.Example4FileDiscovery.json

{
  "animal" :  "elephant" 
}
Code
    JSectionReader
        .Section("JsonSectionReaderUsage.Example4FileDiscovery.Boo.Example4FileDiscovery.json")
        .GetSection("animal").GetObject<string>();
    JSectionReader
        .Section("Example4FileDiscovery.Boo.Example4FileDiscovery.json")
        .GetSection("animal").GetObject<string>();
    JSectionReader
        .Section("Boo.Example4FileDiscovery.json")
        .GetSection("animal").GetObject<string>();
Remark
  1. There are two embedded resources named Example4FileDiscovery.json, so specifing file name as "Example4FileDiscovery.json" will be ambigious and would result in an exception.
  2. The file named has to be more specifically mentioned to avoid ambigiouty.
  3. The valid names for identifying the file are
    • JsonSectionReaderUsage.Example4FileDiscovery.Boo.Example4FileDiscovery.json
    • Example4FileDiscovery.Boo.Example4FileDiscovery.json
    • Boo.Example4FileDiscovery.json
  4. All of the above c sharp statements return the string "elephant"

5. Example5ReadingObject

Data

Example5ReadingObject.json

{
  "person" : {
    "name": "richard",
    "age" :  22
  }
}
Code
JSectionReader.Section("Example5ReadingObject.json").GetSection("person").GetObject<Person>();
Remark
  1. The statement returns a Person object with name as "richard" and Age as 22.

6. Example6ReadingList

Data

Example6ReadingList.json

{
  "numbers" : [5,4,3,2,1] 
}
Code
JSectionReader.Section("Example6ReadingList.json").GetSection("numbers").GetObject<List<int>>();
Remark
  1. The statment returns a List<int> with 5, 4, 3, 2, 1 in it.

7. Example7ReadingAsJson

Data

Example7ReadingAsJson.json

{
  "employees": [
    {
      "name": "John",
      "id": 31432
    },
    {
      "name": "Nash",
      "id": 31433
    }
  ] 
}
Code
new JSectionReader().Read("Example7ReadingAsJson.json").GetSection("employees" , 1).GetJson();
Remark
  1. The statement returns a string {"name":"Nash","id":31433}

8. Example8ListOfList

Reading a table as list of list of objects

Data

Example8ListOfList.json

{
  "data": [
    [ 1, "Monday", "Morning" ],
    [ 2, "Monday", "Afternoon" ],
    [ 3, "Tuesday", "Morning" ],
    [ 4, "Tuesday", "Afternoon" ]
  ] 
}
Code
    new JSectionReader().Read("Example8ListOfList.json").GetSection("data")
        .GetTable(typeof(int), typeof(string), typeof(string))
Remark
    new List<List<object>>()
    {
        new List<object>() {1, "Monday", "Morning"},
        new List<object>() {2, "Monday", "Afternoon"},
        new List<object>() {3, "Tuesday", "Morning"},
        new List<object>() {4, "Tuesday", "Afternoon"},
    };

The statement returns a List<List<object>> as shown above

9. Example9ListOfObject

Reading a table as list of user defined objects

Data

Example9ListOfObject.json

{
  "data": [
    [ 2432, "John", 32 ],
    [ 2222, "Nash", 33 ],
    [ 3421, "Peter", 33 ]
  ] 
}

Code
    new JSectionReader().Read("Example9ListOfObject.json").GetSection("data")
        .GetTableAsObjectList<Employee, int, string, int>(
                (id, name, age) => new Employee()
                {
                    Id = id,
                    Name = name,
                    Age = age,
                });
Remark
  new List<Employee>()
    {
        new Employee(){Id =2432,Name ="John", Age = 32},
        new Employee(){Id =2222,Name ="Nash", Age = 33},
        new Employee(){Id =3421,Name ="Peter", Age = 33},
    };

The statement returns a list of employees as shown above

Release Notes

1.0.2
Fixed the bug of needing to reference Newtonsoft.Json explicitly in the client
Update the usage documentation

1.0.1
Added support for reading a section as a json string

1.0.0
Initial version of Json Section Reader

Version History

Version Downloads Last updated
1.0.2 198 12/8/2018
1.0.1 170 12/3/2018
1.0.0 95 11/27/2018