2009-01-20 54 views
5

我最近偶然發現了一個Google完全無法解釋的看似奇怪的行爲。如果參數爲null,則C#UnitTest - Assert.AreEqual()不會調用Equals。


using Microsoft.VisualStudio.TestTools.UnitTesting; 

class TestClass 
{ 
    public override bool Equals(object obj) 
    { 
     return true; 
    } 
} 

[TestMethod] 
public void TestMethod1() 
{ 
    TestClass t = new TestClass(); 
    Assert.AreEqual (t, null); // fails 
    Assert.IsTrue (t.Equals (null)); // passes 
} 

我希望這個測試成功。但是,在Visual Studio 2008/.NET 3.5中失敗。它是打算如此還是它是一個錯誤?

+1

由於NUnit中的期望值始終是第一個,所以您從約定向後使用AreEqual()。我無法從文檔中知道它是否將null與null進行比較,或者將null與t進行比較,所以我不會稱之爲可靠的測試。 – Ken 2009-08-20 18:32:41

回答

15

您的TestClass違反了Object.Equals的合同。 Assert.AreEqual相當合理地依靠那份合同。

該文檔的狀態(在要求列表):

  • x.Equals(空引用(在Visual Basic中爲Nothing))返回false。
+0

那麼爲什麼最後的斷言會通過?不應該t.Equals(null)返回false,hense不是Assert.Istrue? – 2011-09-06 13:19:48

+0

@borisCallens:斷言傳遞*因爲*實現違反了合同。 `t.Equals(null)`*應該*返回false,但是您可以從實現中看到它實際上*返回true,所以斷開的斷言通過。 – 2011-09-06 13:24:53

5

測試空值時,請勿使用Assert.AreEqual

您必須使用Assert.IsNull()

1

第一次測試失敗。測試「t」是否爲null,不是,因爲您使用新的TestClass對象初始化了t。

第二個測試通過,因爲t.Equals總是返回true。

如果一個測試失敗,整個TestMethod1被標記爲失敗。

1

不,這是正確的 - 你已經初始化t到一個新的TestClass對象,它不是null,所以斷言失敗。

0

如果我找到你的權利,它實際上打算AreEqual(anythingButNull, null)總是返回false?

(編輯)我想知道的原因是因爲根據Equals合同的要求,在單元測試類時不會調用null的測試。因此,因爲AreEqual依靠合同,它不能檢查我的課程是否也符合合同。所以我想我必須使用Assert.IsFalse(blah.Equals(null))的解決方法。

相關問題