我一直在寻找为控制器控制器实现单元测试,特别是围绕测试集合。在MSDN example上使用CollectionAssert.Contains()
确认对象是否出现在列表中。
我有List<myObject>
myObject
实施IEquatable
(即实施Equals()
,以便List<myObject>.Contains()
能够正确辨别存在(或列表中不存在myObject
类型的对象。
然而,CollectionAssert.Contains()
(对于MS-VS测试,而非nunit)功能似乎不会调用Equals()
。
所以我想知道它是否适用于简单数组?
如果没有,它如何比较自定义对象?
我只是将我的断言改为Assert.IsTrue(myList.Contains(myObjectInstance))
。
答案 0 :(得分:5)
查看CollectionAssert.Contains()
的代码,通过迭代集合并使用object.Equals(current, target)
将每个元素与目标元素进行比较来完成实际比较。
因此,您的问题的答案是,如果您没有覆盖object
Equals()
版本的IEquatable<T>
,以便将其发送到您的IEquatable<T>
版本,那么您应该这样做。否则,如果不满足引用相等性,则测试将失败,因为Equals()
的{{1}}重载不会覆盖从object
继承的重载。
答案 1 :(得分:4)
似乎CollectionAssert.Contains没有查看对象的成员值,而是在比较实例的内存地址。以下示例的CollectionAssert将失败,因为尽管它们具有相同的成员值,但obj和obj2 不是同一个实例对象;
MyType obj = new MyType { prop1 = "foo", prop2 = "bar" };
MyType obj2 = new MyType { prop1 = "foo", prop2 = "bar" };
List<MyType> lstObj = new List<MyType> { obj2 };
CollectionAssert.Contains(lstObj, obj);
话虽如此,以下示例的CollectionAssert将成功,因为它将搜索obj2,而不是任何等于obj2的对象;
MyType obj = new MyType { prop1 = "foo", prop2 = "bar" };
MyType obj2 = new MyType { prop1 = "foo", prop2 = "bar" };
List<MyType> lstObj = new List<MyType> { obj2 };
CollectionAssert.Contains(lstObj, obj2);
换句话说,CollectionAssert.Contains比较实例和List(T).Contains“通过使用默认的相等比较器来确定相等性,正如对象的用于T的IEquatable.Equals方法的实现所定义的那样(列表)。“