views:

4639

answers:

5

Hello,

i recently stumbled upon a seemingly weird behavior that Google completely failed to explain.


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
}

I would expect this test to succeed. However, in Visual Studio 2008 / .NET 3.5 it fails. Is it intended to be like that or is it a bug?

+3  A: 

When testing for nulls, do not use Assert.AreEqual.

You have to use Assert.IsNull() for that.

Jon Limjap
+1  A: 

The first test fails. Test if "t" is null, which isn't, because you initialized the t with a new TestClass object.

The second test, passes, because t.Equals always returns true.

If one test fails, the whole TestMethod1 is marked as failed.

Peter
+7  A: 

Your TestClass violates the contract of Object.Equals. Assert.AreEqual is relying on that contract, quite reasonably.

The docs state (in the list of requirements):

  • x.Equals(a null reference (Nothing in Visual Basic)) returns false.
Jon Skeet
+1  A: 

No, it's correct - you've initialised t to a new TestClass object, which isn't null, so the assertion fails.

gkrogers
A: 

If i get you right, it is actually intended that AreEqual(anythingButNull, null) always return false?

(edit) The reason i wondered is because the test for null, as required by the contract of Equals, is not called when unittesting the class. So because AreEqual relies on the contract, it fails to check if my class also complies with the contract. So i guess i have to use the workaround of Assert.IsFalse(blah.Equals(null)).

mafutrct
Yes, exactly a specified in the docs for Object.Equals.
Jon Skeet
Yes, because, simply spoken, (!null==null) has to return false.
Peter