English 中文(简体)
Why Assert. 2. 两种不同的JObject (Newtonsoft.Json.Linq.JObject) got通行证
原标题:Why Assert.Equal two different JObject(Newtonsoft.Json.Linq.JObject) got pass

我很新,可以编组,XUnit和Newtonsoft。 Json. 在我试图比较使用Ausert两种不同的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
        }
    }
}

I don t quite understand how this happens, should I look deep into xUnit or Newtonsoft.Json?

I find there is a DeepEquals method from Newtonsoft.Json, but I am not sure which comparator does xUnit call.

最佳回答

这是xUnit的 asserts子, + Newtonsoft Json.NET。 原因有两个方面:

  • From Newtonsoft side:
    • JToken (base type for "everything" in the library) implements IEnumerable
    • JValue implements IComparable (and IEnumerable because it inherits from JToken) which throws when two JValues are incompatible
  • From xUnit side - if type implements IComparable and comparer throws error, the error is ignored, then if type implements IEnumerable it is treated as a collection and JValue is an empty collection, so as collections they are equal

• Mini:

[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
}

One of the fixes is to use Assert.StrictEqual (works correctly for JValues only):

[Fact]
public void Test2()
{
    var jvLeft = JToken.FromObject(1);
    var jvRight = JToken.FromObject("bar");
    Assert.StrictEqual(jvRight, jvLeft); // output: fail
}

Or use/follow up with the J Token.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
}

注:

问题回答

考虑到这是测试法,因此,报告错误的点名和理由在所称的JSON身体上更好。 Xu尼特·JSON的延伸 包装,以便做以下类似的事情:

JsonAssertion.Equivalent("""
                {
                  "foo": "bar"
                }
                """,
                """
                {
                  "foo": 1
                }
                """);

(I am author of that package.)





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签