zha*_*gr4 10 c# xunit json.net
我对 c#、xUnit 以及 Newtonsoft.Json 都很陌生。当我尝试在单元测试中使用 Assert.Equal() 方法比较两个不同的 JOject 时,它通过了,请参阅下面的示例代码
using Newtonsoft.Json.Linq;
namespace TestProject1
{
public class UnitTest1
{
[Fact]
public void Test1()
{
JObject jobj1 = JObject.FromObject(new { foo = "bar" });
JObject jobj2 = JObject.FromObject(new { foo = 1 });
JObject jobj3 = JObject.FromObject(new { foo = "b" });
Assert.Equal(jobj1, jobj2); // output: pass
Assert.Equal(jobj1, jobj3); // output: failure
Assert.True(jobj1.Equals(jobj2)); // output: failure
Assert.True(jobj1.Equals(jobj3)); // output: failure
}
}
}
Run Code Online (Sandbox Code Playgroud)
我不太明白这是如何发生的,我应该深入研究 xUnit 还是 Newtonsoft.Json?
我发现 Newtonsoft.Json 有一个DeepEquals 方法,但我不确定 xUnit 调用哪个比较器。
Gur*_*ron 11
这是 xUnit 断言 + Newtonsoft Json.NET 的一个错误。原因有两个:
JToken(库中“所有内容”的基本类型)实现IEnumerableJValue实现IComparable(并且IEnumerable因为它继承自JToken),当两个JValues 不兼容时会抛出异常IComparable并且比较器抛出错误,则忽略该错误,然后如果类型实现IEnumerable它被视为集合并且JValue是一个空集合,因此作为集合它们是相等的最小重现如下所示:
[Fact]
public void Test2()
{
var jvLeft = JToken.FromObject(1);
var jvRight = JToken.FromObject("bar");
// some "debug" checks
Assert.True(jvLeft is JValue);
Assert.Empty(jvLeft);
Assert.Throws<FormatException>(() => (jvRight as IComparable).CompareTo(jvLeft));
Assert.Equal(jvRight, jvLeft); // output: pass
}
Run Code Online (Sandbox Code Playgroud)
修复方法之一是使用Assert.StrictEqual(仅适用于JValues):
[Fact]
public void Test2()
{
var jvLeft = JToken.FromObject(1);
var jvRight = JToken.FromObject("bar");
Assert.StrictEqual(jvRight, jvLeft); // output: fail
}
Run Code Online (Sandbox Code Playgroud)
或者使用/跟进JToken.DeepEquals(正如您所发现的):
[Fact]
public void Test12()
{
JObject jobj1 = JObject.FromObject(new { foo = "bar" });
JObject jobj2 = JObject.FromObject(new { foo = 1 });
Assert.Equal(jobj1, jobj2); // output: pass
Assert.True(JToken.DeepEquals(jobj1, jobj2)); // output: fail
}
Run Code Online (Sandbox Code Playgroud)
笔记:
| 归档时间: |
|
| 查看次数: |
358 次 |
| 最近记录: |