CollectionAssert.Contains(myList, myItem) != Assert.IsTrue(myList.Contains(myItem))
I have been looking at implementing unit tests for a controller controller, specifically around testing collections. On the MSDN example the use of CollectionAssert.Contains()
confirms whether an object appears in a list.
I have a List<myObject>
where myObject
implements IEquatable
(i.e. implementing a Equals()
, so that the List<myObject>.Contains()
is able to correctly discern the existence (or non-existence of an object of type myObject
in the list).
The CollectionAssert.Contains()
(for an MS-VS test, not nunit) 开发者_JS百科function however, does not appear to call Equals()
.
So I'm wondering if it's for use on simple arrays?
If not, how is it able to compare custom objects?
I've simply changed my assert in this case to Assert.IsTrue(myList.Contains(myObjectInstance))
.
Looking at the code for CollectionAssert.Contains()
, the actual comparison is done by iterating the collection, and comparing each element to the target elements with object.Equals(current, target)
.
So the answer to your question is that if you haven't overridden the object
version of Equals()
so that it dispatches to your IEquatable<T>
version, you should. Otherwise the test is going to fail if reference equality isn't satisfied, since the IEquatable<T>
overload of Equals()
doesn't override the overload inherited from object
.
It seems CollectionAssert.Contains is not looking at your object's member values, but is comparing instances' memory address. The following example's CollectionAssert will fail, due to the fact that, although they have the same member values, obj and obj2 are not the same instance object;
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);
That being said, the following example's CollectionAssert will succeed because it will be searching for obj2, and not any object that equals 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);
In other words, CollectionAssert.Contains compares instances and List(T).Contains "determines equality by using the default equality comparer, as defined by the object's implementation of the IEquatable.Equals method for T (the type of values in the list)."
Reference : http://msdn.microsoft.com/en-us/library/bhkz42b3.aspx
精彩评论