C# 使用Assert.AreEqual()比较两个对象

C# 使用Assert.AreEqual()比较两个对象,c#,unit-testing,object,compare,xunit,C#,Unit Testing,Object,Compare,Xunit,我第一次在visual studio c中编写测试用例,我有一个返回对象列表的方法,我想使用Assert.AreEqual()方法将它与另一个对象列表进行比较 我尝试过这样做,但即使两个对象完全相同,断言也会失败 我想知道这个方法,两个参数是比较引用还是对象的内容 我是否必须重载==运算符才能使其工作?Assert.AreEqual()比较引用。通常在比较列表时,我会比较项目的数量,而不是列表中某个确切项目的某些属性,或者直接比较列表中的项目(但同样是参考) 如果要按内容比较对象,则必须实现一些

我第一次在visual studio c中编写测试用例,我有一个返回对象列表的方法,我想使用
Assert.AreEqual()
方法将它与另一个对象列表进行比较

我尝试过这样做,但即使两个对象完全相同,断言也会失败

我想知道这个方法,两个参数是比较引用还是对象的内容

我是否必须重载
==
运算符才能使其工作?

Assert.AreEqual()比较引用。通常在比较列表时,我会比较项目的数量,而不是列表中某个确切项目的某些属性,或者直接比较列表中的项目(但同样是参考)


如果要按内容比较对象,则必须实现一些递归对象比较器,但我认为这不适合单元测试,因为您希望它们总是以尽可能快的速度运行。

NET上的
xUnit
中的Assert.AreEqual将检查对象是否相同,但是对象标识不同于值相等。您似乎在寻找值相等。即“我的列表中的对象是否具有相同的值?”这就是为什么它“失败”两个列表不相同,即使每个列表中每个对象的值可能表示相同的值

通常在测试工作中,测试集合和关键元素的计数就足够了

var count = listA.Count;
Assert.AreEqual(count,listB.Count);
Assert.AreEqual(listA.First(),listB.first());
Assert.AreEqual(listA.Last(),listB.Last());
Assert.AreEqual(listA[count/2],listB[count/2]);

最后一个测试不必位于中间元素,它只是用来测试列表中的一个元素。它不是随机元素的唯一原因是您希望能够重现您的测试结果。

如果您使用的是
NUnit
,文档中是这么说的

从版本2.2开始,还对 比较一维数组。两个阵列将被视为 如果它们的长度相同,并且每个 相应的元素是相等的。注:多维数组, 嵌套数组(数组的数组)和其他集合类型,如 当前不支持ArrayList

通常,如果要比较两个对象,并且希望基于值的相等,则必须重写
Equals
方法

要实现您想要的目标,请尝试以下方法:

class Person 
{
    public string Firstname {get; set;}
    public string Lastname {get; set;} 

    public override bool Equals(object other) 
    {
      var toCompareWith = other as Person;
      if (toCompareWith == null) 
        return false;
      return this.Firstname ==  toCompareWith.Firstname && 
          this.Lastname ==  toCompareWith.Lastname; 
    }
}  
在单元测试中:

Assert.AreEqual(expectedList.ToArray(), actualList.ToArray());

这些答案对于这个问题来说太复杂了。比较两个列表不需要重写,也不需要分解多个断言。 Microsoft使用以下类CollectionAssert

CollectionAssert.AreEqual(expectedList, actualList)
这适用于列表、字典和实现ICollection接口的任何其他工具

microsoft文档位于以下位置,详细说明了可以对集合进行的各种类型的断言


但是,正如@Bart所提到的,这在(复杂)对象列表上并没有像预期的那样起作用,对于这些情况,Equals方法可能仍然需要被覆盖。

您可以序列化它们并测试结果字符串。

查看本文:值得注意的是,当您覆盖Equals时,强烈建议您也使用合理的实现覆盖GetHashCode。事实上,如果您没有这样做,它将生成一个编译器警告。非常感谢!节省了很多时间,加上今天学到了一些新东西对于@a-1提到的问题,答案有点复杂。但是,
CollectionAssert.AreEqual
似乎只适用于基本类型/标量属性的列表,而不适用于(复杂)对象的列表。因为我有两个列表,都有一个对象,其中包含完全相同的值,但列表仍然不相等。因此,我仍然需要覆盖Objects类的
Equals
方法,然后才能工作:(.缺乏细节,但这是迄今为止最好的答案。我并不真的想知道为什么它没有做我想要的事情,而是实现我目标的一种方法,就是这样。