繁体   English   中英

如何使用 NUnit 单元测试比较复杂对象

[英]How to compare complex objects with NUnit Unit Test

学习如何使用 NUnit 编写单元测试。

努力比较两个复杂的对象。

这里有一个非常相似的问题的答案, 使用 Assert.AreEqual() 比较两个对象,尽管看起来您应该覆盖对象上的Equals() - 鉴于可能有多少对象,这并不理想您想要比较,更不用说对象及其嵌套对象上可能存在的属性数量了。

给定示例对象:

   public class AMockObject
   {
       public int Id { get; set; }
       public ICollection<int> Numbers { get; set; }

       public AMockObject()
       {
          Numbers = new List<int>();
       }           
    }

我想比较这个对象的两个单独实例具有相同的值,我发现Assert.AreEqual()并没有真正达到我的预期。

例如,所有这些都失败了:

// Example 1
AMockObject a = new AMockObject();
AMockObject b = new AMockObject();
Assert.AreEqual(a,b); // Fails - they're not equal

// Example 2
AMockObject a = new AMockObject() { Id = 1 };
AMockObject b = new AMockObject() { Id = 1 };
Assert.AreEqual(a, b); // Also fails

// Example 3
AMockObject a = new AMockObject() { Id = 1 };
a.Numbers.Add(1);
a.Numbers.Add(2);
a.Numbers.Add(3);    
AMockObject b = new AMockObject() { Id = 1 };
b.Numbers.Add(1);
b.Numbers.Add(2);
b.Numbers.Add(3);    
Assert.AreEqual(a, b); // also fails

我们有代码可以克隆各种对象,其中一些对象非常大。 鉴于这是一件很常见的事情,是否有一种同样常见的方法来测试两个对象在属性值级别是否相同?

此处的示例有两个属性。 在现实世界中,我有一个具有几十个属性的对象,其中一些是其他复杂对象的列表。

目前,我正在序列化对象并比较字符串,尽管这感觉不太理想。

单元测试中使用了一种称为Fluent Assertions的工具,它能够进行此类比较。

但是请注意

当两个对象图具有相同名称的具有相同值的属性时,对象是等效的,而不管这些对象的类型如何。 如果一种类型可以转换为另一种类型并且结果相等,则两个属性也相等。 只要集合实现 System.Collections.IEnumerable 并且集合中的所有项目在结构上都相等,就会忽略集合属性的类型。 请注意,实际行为由 FluentAssertions.AssertionOptions 管理的全局默认值决定。

using FluentAssertions;

//...

// Example 1
AMockObject a = new AMockObject();
AMockObject b = new AMockObject();
a.ShouldBeEquivalentTo(b); // Asserts that an object is equivalent to another object.

// Example 2
AMockObject a = new AMockObject() { Id = 1 };
AMockObject b = new AMockObject() { Id = 1 };
a.ShouldBeEquivalentTo(b); //Asserts that an object is equivalent to another object.

// Example 3
AMockObject a = new AMockObject() { Id = 1 };
a.Numbers.Add(1);
a.Numbers.Add(2);
a.Numbers.Add(3);    
AMockObject b = new AMockObject() { Id = 1 };
b.Numbers.Add(1);
b.Numbers.Add(2);
b.Numbers.Add(3);
a.ShouldBeEquivalentTo(b)    
a.Numbers.ShouldAllBeEquivalentTo(b.Numbers); // Asserts that a collection of objects is equivalent to another collection of objects.

文档在这里

由于没有其他任何变化,您可以简单地比较创建的对象的属性值吗?

您可以使用反射(请参阅使用反射获取字段)并遍历两个类中的字段。 FieldInfo.GetValue() 应该为您提供要比较的值。

将其序列化为 Json 并进行比较

使用 Newtonsoft.Json.JsonConverter 就可以了。

var expected = JsonConvert.SerializeObject(a);
var result = JsonConvert.SerializeObject(b);

Assert.AreEqual(expected, result);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM