CollectionAssert.Contains(myList,myItem)!= Assert.IsTrue(myList.Contains(myItem))

时间:2011-09-21 16:04:23

标签: c# .net unit-testing mstest

我一直在寻找为控制器控制器实现单元测试,特别是围绕测试集合。在MSDN example上使用CollectionAssert.Contains()确认对象是否出现在列表中。

我有List<myObject> myObject实施IEquatable(即实施Equals(),以便List<myObject>.Contains()能够正确辨别存在(或列表中不存在myObject类型的对象。

然而,CollectionAssert.Contains()(对于MS-VS测试,而非nunit)功能似乎不会调用Equals()。 所以我想知道它是否适用于简单数组? 如果没有,它如何比较自定义对象?

我只是将我的断言改为Assert.IsTrue(myList.Contains(myObjectInstance))

2 个答案:

答案 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方法的实现所定义的那样(列表)。“

参考:http://msdn.microsoft.com/en-us/library/bhkz42b3.aspx