如何使用C#比较两个Json对象

Nan*_*712 6 c# unit-testing json.net assertion fluent-assertions

我有两个Json对象需要进行比较.我正在使用Newtonsoft库进行Json解析.

string InstanceExpected = jsonExpected;
string InstanceActual = jsonActual;
var InstanceObjExpected = JObject.Parse(InstanceExpected);
var InstanceObjActual = JObject.Parse(InstanceActual);
Run Code Online (Sandbox Code Playgroud)

我正在使用Fluent Assertions对它进行比较.但问题是Fluent断言仅在属性count/names不匹配时才会失败.如果json值不同则会通过.当值不同时,我要求失败.

InstanceObjActual.Should().BeEquivalentTo(InstanceObjExpected);
Run Code Online (Sandbox Code Playgroud)

例如,我有实际和预期的json比较如下.并且使用上面的比较方式使得它们传递错误.

{
  "Name": "20181004164456",
  "objectId": "4ea9b00b-d601-44af-a990-3034af18fdb1%>"  
}

{
  "Name": "AAAAAAAAAAAA",
  "objectId": "4ea9b00b-d601-44af-a990-3034af18fdb1%>"  
}
Run Code Online (Sandbox Code Playgroud)

Rui*_*mba 13

我做了一些挖掘,并且能够找出为什么OP的测试代码没有按预期运行.我能够通过安装和使用FluentAssertions.Json nuget包来修复它.

一件重要的事情:

一定要包括using FluentAssertions.Json否则可能会出现误报.

测试代码如下:

using FluentAssertions;
using FluentAssertions.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NUnit.Framework;

[TestFixture]
public class JsonTests
{
    [Test]
    public void JsonObject_ShouldBeEqualAsExpected()
    {
        JToken expected = JToken.Parse(@"{ ""Name"": ""20181004164456"", ""objectId"": ""4ea9b00b-d601-44af-a990-3034af18fdb1%>"" }");
        JToken actual = JToken.Parse(@"{ ""Name"": ""AAAAAAAAAAAA"", ""objectId"": ""4ea9b00b-d601-44af-a990-3034af18fdb1%>"" }");

        actual.Should().BeEquivalentTo(expected);
    }
}
Run Code Online (Sandbox Code Playgroud)

运行测试:

单元测试结果


Jes*_*Wit 12

考虑使用JToken.DeepEquals()Newtonsoft提供的方法.无论您使用哪种测试框架,它看起来都会像这样:

Console.WriteLine(JToken.DeepEquals(InstanceObjActual, InstanceObjExpected));
// false
Run Code Online (Sandbox Code Playgroud)

  • 把我打败了大约 10 秒 :) 这是正确的答案。 (2认同)
  • 我发现在单元测试中使用 `JToken.DeepEquals` 的唯一问题是无法找到 json 字符串中的差异。将 json 反序列化为 C# 对象并比较它们会提供更好的错误消息(请参阅我附在答案中的屏幕截图)。 (2认同)
  • @RuiJarimba 当然,反序列化为 C# 对象会给出更好的错误消息,但我没有在所有地方使用这种方法,因为它是一个测试项目,我们处理各种 Json 响应,并且为每个对象创建类对象的努力非常高,并且太多的过载。 (2认同)