Socolin.TestUtils.JsonComparer 1.3.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Socolin.TestUtils.JsonComparer --version 1.3.0
NuGet\Install-Package Socolin.TestUtils.JsonComparer -Version 1.3.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Socolin.TestUtils.JsonComparer" Version="1.3.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Socolin.TestUtils.JsonComparer --version 1.3.0
#r "nuget: Socolin.TestUtils.JsonComparer, 1.3.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Socolin.TestUtils.JsonComparer as a Cake Addin
#addin nuget:?package=Socolin.TestUtils.JsonComparer&version=1.3.0

// Install Socolin.TestUtils.JsonComparer as a Cake Tool
#tool nuget:?package=Socolin.TestUtils.JsonComparer&version=1.3.0

Json Comparer

This library provides a simple way to compare two JSON, with an easily readable output to find what differs.

Features:

  • Compare JSON and returns a list of errors.
  • Compare a value using a regex
  • Capture a value

NuGet: https://www.nuget.org/packages/Socolin.TestUtils.JsonComparer/


Simple compare

Example

Code
const string expectedJson = @"{
    ""a"":1,
    ""b"":""abc""
}";
const string actualJson = @"{
    ""a"":42,
    ""b"":""abc""
}";
var jsonComparer = TestUtils.JsonComparer.JsonComparer.GetDefault();
var errors = jsonComparer.Compare(expectedJson, actualJson);
Console.WriteLine(JsonComparerOutputFormatter.GetReadableMessage(expectedJson, actualJson, errors));
Output
Given json does not match expected one:
  - a: Invalid value, expected '1' but found '42'

--- expected
+++ actual
 {
-  "a": 1,
+  "a": 42,
   "b": "abc"
 }

Compare using regex

It's possible to compare strings with a regex, using a custom object with a property __match.

For example, in the following json, to compare the key compareMeWithARegex with the [a-z]+

{
  "compareMeWithARegex": "something"
}

The expected json given to the comparer should be

{
  "compareMeWithARegex": {
    "__match": {
      "regex": "[a-z]+"
    }
  }
}

Example 1

Code
Console.WriteLine("==== MatchExample.Test1 ==== ");
const string expectedJson = @"{
    ""a"":{
        ""__match"":{
            ""regex"": ""\\d+""
        }
    },
    ""b"":""abc""
}";
const string actualJson = @"{
    ""a"":""42"",
    ""b"":""abc""
}";
var jsonComparer = TestUtils.JsonComparer.JsonComparer.GetDefault();
var errors = jsonComparer.Compare(expectedJson, actualJson);
Console.WriteLine(JsonComparerOutputFormatter.GetReadableMessage(expectedJson, actualJson, errors));
Output
No differences found

Example 2

Code
const string expectedJson = @"{
    ""a"":{
        ""__match"":{
            ""regex"": ""\\d+""
        }
    },
    ""b"":""abc""
}";
const string actualJson = @"{
    ""a"":""abc"",
    ""b"":""abc""
}";
var jsonComparer = TestUtils.JsonComparer.JsonComparer.GetDefault();
var errors = jsonComparer.Compare(expectedJson, actualJson);
Console.WriteLine(JsonComparerOutputFormatter.GetReadableMessage(expectedJson, actualJson, errors));
Output
Given json does not match expected one:
  - a: Invalid value, 'abc' should match regex '\d+'

--- expected
+++ actual
 {
-  "a": {
-    "__match": {
-      "regex": "\\d+"
-    }
-  },
+  "a": "abc",
   "b": "abc"
 }

Note

If there is any errors, to improve the readability of the output, the match objects are replaced by their matching value in the expectedJToken.

Example
Code
var expectedJToken = JToken.Parse(@"{
    ""a"":{
        ""__match"":{
            ""regex"": "".+""
        }
    },
    ""b"":""abc""
}");
var actualJToken = JToken.Parse(@"{
    ""a"":""abc"",
    ""b"":""def""
}");
var jsonComparer = TestUtils.JsonComparer.JsonComparer.GetDefault();
var errors = jsonComparer.Compare(expectedJToken, actualJToken);
Console.WriteLine(JsonComparerOutputFormatter.GetReadableMessage(expectedJToken, actualJToken, errors));
Output
Captured value: name=some-name token=42
Given json does not match expected one:
  - b: Invalid value, expected 'abc' but found 'def'

--- expected
+++ actual
 {
   "a": 42,
-  "b": "abc"
+  "b": "def"
 }

Compare using type

It's possible to compare object and expect to be of a certain type, without looking at the value, using a custom object with a property __match.

For example, in the following json, to verify the value associated to the key compareMeByType is an integer

{
  "compareMeByType": 42
}

The expected json given to the comparer should be

{
  "compareMeByType": {
    "__match": {
      "type": "integer"
    }
  }
}

Example

Code
Console.WriteLine("==== MatchExample.Test4 ==== ");
const string expectedJson = @"{
    ""a"":{
        ""__match"":{
            ""type"": ""integer""
        }
    },
    ""b"":""abc""
}";
const string actualJson = @"{
    ""a"":42,
    ""b"":""abc""
}";
var jsonComparer = TestUtils.JsonComparer.JsonComparer.GetDefault();
var errors = jsonComparer.Compare(expectedJson, actualJson);
Console.WriteLine(JsonComparerOutputFormatter.GetReadableMessage(expectedJson, actualJson, errors));
Output
No differences found

Capture a value

It's possible to capture some values when a value is compared with a capture object, a callback will be called.

This can be used in functional testing to easily capture a value from a JSON and then use this value later.

For example to compare and extract the id field of the following JSON

{
  "id": 4
}

You should use the following capture object

{
  "id": {
    "__capture": {
      "name": "someCaptureName",
      "type": "integer"
    }
  }
}

Example

Code
var jsonComparer = TestUtils.JsonComparer.JsonComparer.GetDefault(((captureName, token) => {
  Console.WriteLine($"Captured value: name={captureName} token={token}");
}));


const string expectedJson = @"{""a"":{""__capture"":{""name"": ""some-name"", ""type"":""integer""}}, ""b"":""abc""}";
const string actualJson = @"{""a"":42, ""b"":""abc""}";

var errors = jsonComparer.Compare(expectedJson, actualJson);
Console.WriteLine(JsonComparerOutputFormatter.GetReadableMessage(expectedJson, actualJson, errors));

Output

Captured value: name=some-name token=42
No differences found

Note

If there is any errors, to improve the readability of the output, the capture objects are replaced by their matching value in the expectedJToken.

Example
Code
var jsonComparer = TestUtils.JsonComparer.JsonComparer.GetDefault(((captureName, token) => {
  Console.WriteLine($"Captured value: name={captureName} token={token}");
}));

const string expectedJson = @"{""a"":{""__capture"":{""name"": ""some-name"", ""type"":""integer""}}, ""b"":""abc""}";
const string actualJson = @"{""a"":42, ""b"":""def""}";


var errors = jsonComparer.Compare(expectedJson, actualJson);
Console.WriteLine(JsonComparerOutputFormatter.GetReadableMessage(expectedJson, actualJson, errors));
Output
Captured value: name=some-name token=42
Given json does not match expected one:
  - b: Invalid value, expected 'abc' but found 'def'

--- expected
+++ actual
 {
   "a": 42,
-  "b": "abc"
+  "b": "def"
 }
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Socolin.TestUtils.JsonComparer:

Package Downloads
Socolin.TestUtils.JsonComparer.NUnitExtensions

Extensions of NUnit to easily use Socolin.TestUtils.JsonComparer.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.16.0 5,280 1/22/2023
1.15.1 578 12/24/2022
1.15.0 424 12/24/2022
1.14.0 3,272 6/12/2022
1.13.0 1,142 3/20/2022
1.12.0 58,173 12/27/2020
1.11.0 391 12/26/2020
1.10.2 436 12/15/2020
1.10.1 469 11/19/2020
1.10.0 761 11/19/2020
1.9.0 2,605 8/14/2020
1.8.1 1,923 7/1/2020
1.8.0 666 6/30/2020
1.7.1 1,070 3/19/2020
1.7.0 1,094 2/26/2020
1.6.0 554 1/14/2020
1.5.1 790 6/23/2019
1.5.0 616 4/26/2019
1.4.0 824 12/28/2018
1.3.0 635 12/27/2018
1.2.0 1,317 12/6/2018
1.1.0 612 12/5/2018
1.0.0 636 12/4/2018