2011-09-21 45 views
4

我一直在考慮爲控制器控制器實現單元測試,特別是圍繞測試集合。在MSDN example上,使用CollectionAssert.Contains()確認對象是否出現在列表中。CollectionAssert.Contains(myList,myItem)!= Assert.IsTrue(myList.Contains(myItem))

我有一個List<myObject>其中myObject器具IEquatable(即實施Equals(),使得List<myObject>.Contains()能夠正確地辨別是否存在(或在列表中myObject類型的對象)的不存在。

的但是,似乎並沒有調用Equals() 所以我想知道它是否適用於簡單的數組? 如果不是,它如何能夠比較自定義對象?

(對於MS-VS測試,而不是nunit)

我只是在這種情況下將我的斷言改爲Assert.IsTrue(myList.Contains(myObjectInstance))

+0

RE:您的評論。這也是我的觀點!這兩種方法有不同的行爲,所以你必須以某種方式來解釋。要麼你可以調用'IsTrue(myList.Contains(item))',或者覆蓋'Equals()'的'object'版本,並將它委託給你的'IEquatable'版本。 – dlev

回答

5

查看CollectionAssert.Contains()的代碼,實際比較是通過迭代集合並將每個元素與目標元素進行比較來完成的,其中object.Equals(current, target)

因此,您的問題的答案是,如果您尚未覆蓋版本Equals()以便它發送到IEquatable<T>版本,您應該。否則,如果不滿足參考相等性,測試將失敗,因爲Equals()IEquatable<T>過載不會覆蓋從object繼承的過載。

+0

「謝謝,但這就是我的觀點,我已經實現的等式是由list <>。contains包含的,但不是由collectableassert.contains ...所以,就像在線程的標題中一樣,我有assert.istrue和list <>。如果collectableassert.Contains失敗,則包含通過的地方,這不是nunit測試,而是使用vs測試,所以我不確定代碼的作用,Nunit的行爲可能不同。那裏還有技術上的明智之舉。「 - 對於丹尼爾[他似乎還沒有代表評論] – Gishu

2

看來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比較實例和列表(T)。載「通過使用默認的相等比較器確定平等,由對象的實現T的IEquatable.Equals方法的類型(所限定列表中的值)。「

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

相關問題