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

问题描述 投票:0回答:6

我第一次在 Visual Studio C# 中编写测试用例,我有一个返回对象列表的方法,我想使用

Assert.AreEqual()
方法将其与另一个对象列表进行比较。

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

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

我是否必须重载

==
运算符才能使其工作?

c# unit-testing object compare xunit
6个回答
52
投票

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

CollectionAssert.AreEqual(expectedList, actualList)

这适用于列表、字典以及任何其他实现 ICollection 接口的内容。

微软文档位于以下位置,详细介绍了可以对集合进行的各种类型的断言

http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.collectionassert.aspx

但是,正如 @Bart 所提到的,这在(复杂)对象列表上无法按预期工作,并且对于这些情况,可能仍需要覆盖 Equals 方法。


27
投票

如果您正在使用

NUnit
,这就是文档所说的

从2.2版本开始,还做出了特殊规定 比较一维数组。两个数组将被视为 如果它们的长度相同并且每个都等于 Assert.AreEqual 对应的元素相等。注意:多维数组, 嵌套数组(数组的数组)和其他集合类型,例如 目前不支持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());

9
投票

您可以序列化它们并测试生成的字符串。


4
投票
.NET 上的

xUnit

 中的 
Assert.AreEqual 将检查对象是否相同,但是对象标识与值相等性不同,看起来您正在寻找值相等性。 IE。 “我的列表中的对象具有相同的值吗?”这就是为什么它“失败”的原因是两个列表不相同,即使每个列表中每个对象的值可能表示相同的值。

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

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]);

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


1
投票

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

如果您想按内容比较对象,则必须实现一些递归对象比较器,但我认为它不适合单元测试,因为您希望它们始终尽可能快地运行。


0
投票

这是一个旧的,但我会给出我的意见。仅当您需要使对象上的少数属性相同时,这才有效。您可以使用 Linq 选择元组集合。

CollectionAssert.AreEqual(ExpectedObject.Select(x => (x.firstProp, x.SecondProp, x.thirdProp.IsPretty.Deep)).ToArray(), createOrUpdateCNameRecordAsyncCalls.Select(x => (x.firstProp, x.SecondProp, x.thirdProp.IsPretty.Deep)).ToArray());
© www.soinside.com 2019 - 2024. All rights reserved.