Skip to content

Extension method for the Shouldly .NET library to work with JSON strings

License

Notifications You must be signed in to change notification settings

Namoshek/Shouldly.Json

Repository files navigation

Shouldly.Json Nuget

Coverage Quality Gate Status Maintainability Rating Reliability Rating Security Rating Vulnerabilities

Shouldly.Json was created by, and is maintained by Marvin Mall. It provides extension methods for the Shouldly library to compare JSON strings.

Installation

The package can be found on nuget.org. You can install the package with:

Install-Package Shouldly.Json

Usage

The library provides multiple methods for comparing JSON strings.

Basic JSON Validation

Use ShouldBeValidJson() to validate if the given string is valid JSON syntax. Be aware that besides arrays and objects, JSON also supports other types like strings, numbers, booleans, and null in the root of a string.

var json = @"{""name"": ""John"", ""age"": 30}";

json.ShouldBeValidJson();

Use ShouldBeJsonObject() and ShouldBeJsonArray() to check if the given string is a valid JSON object or array.

var json1 = @"{""name"": ""John"", ""age"": 30}";
var json2 = @"[1, 2, 3]";

json1.ShouldBeJsonObject();
json2.ShouldBeJsonArray();

Semantic JSON Equality

Use ShouldBeSemanticallySameJson() to compare two JSON strings for semantic equality. This means:

  • Property order in objects doesn't matter
  • Whitespace and formatting doesn't matter
  • Numbers with same value but different representation (e.g., 1.0 and 1.00) are considered equal
  • Array order matters
var json1 = @"{""name"": ""John"", ""age"": 30}";
var json2 = @"{""age"": 30, ""name"": ""John""}";
var json3 = @"{""name"": ""John"", ""age"": 31}";

json1.ShouldBeSemanticallySameJson(json2); // Succeeds
json1.ShouldBeSemanticallySameJson(json3); // Fails

JSON Subtree Matching

Use ShouldBeJsonSubtreeOf() to verify that one JSON structure is contained within another. This means:

  • The actual JSON must be a subset of the expected JSON
  • Missing properties in objects are allowed
  • Arrays must match exactly (including length and order), but objects in arrays are handled like other objects
var json1 = @"{""name"": ""John""}";
var json2 = @"{""name"": ""John"", ""age"": 30}";
var json3 = @"{""name"": ""Adrian""}";
var json4 = @"{""firstName"": ""John""}";

json1.ShouldBeJsonSubtreeOf(json2); // Succeeds
json1.ShouldBeJsonSubtreeOf(json3); // Fails
json1.ShouldBeJsonSubtreeOf(json4); // Fails

JSON Schema Validation

Use ShouldMatchJsonSchema() to validate a JSON string against a JSON Schema. This allows you to verify that JSON data conforms to an expected structure and format.

var json = @"{""name"": ""John"", ""age"": 30}";
var schema = @"{
    ""type"": ""object"",
    ""properties"": {
        ""name"": { ""type"": ""string"" },
        ""age"": { ""type"": ""integer"", ""minimum"": 0 }
    },
    ""required"": [""name"", ""age""]
}";

json.ShouldMatchJsonSchema(schema);

Property Existence Validation

Use ShouldHaveJsonProperty() to check if a JSON string has a specific property. You can also provide a JSON pointer to check the existence of a property at a specific path.

var json = @"{""user"": {""name"": ""John""}}";

json.ShouldHaveJsonProperty("/user/name");

Property Value Validation

Use ShouldHaveJsonValue() to check if a JSON string has a specific property with a specific value. You can also provide a JSON pointer to check the value of a property at a specific path.

var json1 = @"{""user"": {""name"": ""John""}}";
var json2 = @"{""users"": [{""name"": ""John""}, {""name"": ""Jane""}]}";

json1.ShouldHaveJsonValue("/user/name", "John");
json2.ShouldHaveJsonValue("/users/2/name", "Jane");

Use any of the other ShouldHaveJsonValue methods to check the value of a property at a specific path with different comparators.

var json = @"{""user"": {""name"": ""John"", ""age"": 30}}";

json.ShouldHaveJsonValueLessThan("/user/age", 31);
json.ShouldHaveJsonValueLessThanOrEqualTo("/user/age", 30);
json.ShouldHaveJsonValueGreaterThan("/user/age", 29);
json.ShouldHaveJsonValueGreaterThanOrEqualTo("/user/age", 30);
json.ShouldHaveJsonValueBetween("/user/age", 29, 31);

Special methods for date/time values are also available. They work very similar but provide better semantics for date/time values. Also be aware that those methods use the upper bound exclusively while the other methods inclusively.

var json = @"{""user"": {""name"": ""John"", ""birthDate"": ""1990-01-01""}}";

json.ShouldHaveJsonDateBefore("/user/birthDate", new DateTime(1990, 1, 2));
json.ShouldHaveJsonDateBeforeOrEqualTo("/user/birthDate", new DateTime(1990, 1, 2));
json.ShouldHaveJsonDateAfter("/user/birthDate", new DateTime(1990, 1, 1));
json.ShouldHaveJsonDateAfterOrEqualTo("/user/birthDate", new DateTime(1990, 1, 1));
json.ShouldHaveJsonDateBetween("/user/birthDate", new DateTime(1989, 1, 1), new DateTime(1991, 1, 1));

Array Length Validation

Use ShouldHaveJsonArrayCount() to check the length of an array. You can also provide a JSON pointer to check the length of an array at a specific path.

var json1 = @"[1, 2, 3]";
var json2 = @"{""users"": [""John"", ""Jane""]}";

json1.ShouldHaveJsonArrayCount(3); // root array
json2.ShouldHaveJsonArrayCount(2, "/users"); // nested array

License

This library is open-sourced software licensed under the MIT license.

About

Extension method for the Shouldly .NET library to work with JSON strings

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages