我有一个类MyCustomClass:
public MyCustomClass
{
public MyCustomClass()
{
MyObject = new List<MyCustomObject>();
}
public List<MyCustomObject> MyObject {get; set;}
}
在测试中:
List<MyCustomObject> aux = new List<MyCustomObject>();
MyCustomClass oClass = new MyCustomClass();
Assert.AreEqual(aux, oClass.MyObject)
测试失败了,为什么?每个属性,静态成员等都是相同的。
答案 0 :(得分:19)
在这种情况下,Assert.AreEqual
将检查这两个对象是否相同,但它们不是。您应该使用CollectionAssert.AreEqual
代替,如果两个“具有相同顺序和数量的相同元素,则返回true。”
答案 1 :(得分:4)
作为already answered,两个具有零元素的相同类型的列表不被视为相等。
这背后的原因是,AreEqual
实际调用aux.AreEqual(oClass.MyObject)
,使用对象自己的相等实现。因为List<T>
没有覆盖它,所以它回退到Object
中的实现,这是一个简单的引用相等性检查。这两个列表显然不是相同的参考,因此,它们不被认为是平等的。
因为Equals
方法存在且在Object
上是虚拟的,所以您自己的类可以覆盖Equals
,以便为参数相等提供另一个相等的概念。这是在像String
这样的对象上完成的,如果数据相同,它们即使对于不同的引用也是相等的。
答案 2 :(得分:0)
我使用dotPeek反编译Assert.AreEqual
(在Microsoft.VisualStudio.QualityTools.UnitTestFramework
GAC汇编中),发现Assert.AreEqual(aux, oClass.MyObject)
最终会导致以下调用aux
是expected
而oClass.MyObject
是actual
:
object.Equals((object) expected, (object) actual)
从documentation我们读到的静态object.Equals(Object, Object)
:
静态Equals(Object,Object)方法指示是否两个 对象,objA和objB是相等的。它还使您可以测试对象 其值为null,表示相等。它比较了objA和objB 平等如下:
确定两个对象是否代表同一个对象 参考。如果是,则该方法返回true。这个测试是 相当于调用ReferenceEquals方法。另外,如果两者兼而有之 objA和objB为null,该方法返回true。
确定objA或objB是否为空。如果是,则返回 假的。
如果两个对象不表示相同的对象引用和 既不是null,它调用objA.Equals(objB)并返回结果。 这意味着如果objA重写Object.Equals(Object)方法, 调用此覆盖。
现在,List<T>
已知是一个引用类型,我们知道您要比较的两个列表都不为null,因此两个对象之间的最终比较将是
expected.Equals(actual)
由于List<T>
未覆盖Equals
,因此它使用执行引用比较的基础对象实现,因此失败(expected
和actual
为&#34;新的&#34;分开)。
你想要的是结构比较,即列表中元素的成对相等。请参阅@ReedCopsey答案以获取正确的断言(CollectionAssert.AreEqual
)。