C#UnitTest-引数がnullの場合、Assert.AreEqual()はEqualsを呼び出しません
-
19-08-2019 - |
質問
私は最近、グーグルが完全に説明するのに失敗した一見奇妙な振る舞いにつまずいた。
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では失敗します。そのようにするつもりですか、それともバグですか?
解決
TestClassが Object.Equals
の契約に違反しています。 Assert.AreEqual
はかなり合理的にその契約に依存しています。
ドキュメントの状態(要件のリスト内):
- x.Equals(null参照(Visual BasicではNothing))はfalseを返します。
他のヒント
ヌルをテストするときは、Assert.AreEqual
を使用しないでください。
そのためにはAssert.IsNull()
を使用する必要があります。
最初のテストは失敗します。 <!> quot; t <!> quot;かどうかをテストします。新しいTestClassオブジェクトでtを初期化したため、そうではありません。
t.Equalsは常にtrueを返すため、2番目のテストに合格します。
1つのテストが失敗すると、TestMethod1全体が失敗としてマークされます。
いいえ、正しい-tを新しいTestClassオブジェクトに初期化しましたが、nullではないため、アサーションは失敗します。
私があなたを正しく理解するなら、実際にはAreEqual(anythingButNull, null)
は常にfalseを返すことを意図していますか?
(edit)私が疑問に思った理由は、Equalsの契約で要求されているnullのテストは、クラスのユニットテスト時に呼び出されないからです。そのため、AreEqualは契約に依存しているため、クラスが契約にも準拠しているかどうかを確認できません。したがって、Assert.IsFalse(blah.Equals(null))
の回避策を使用する必要があると思います。