C # UnitTest - Assert.AreEqual () не вызывает Equals, если аргумент нулевой - PullRequest
5 голосов
/ 20 января 2009

Недавно я наткнулся на странное поведение, которое Google совершенно не смог объяснить.


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 это не удается. Это должно быть так или это ошибка?

Ответы [ 5 ]

15 голосов
/ 20 января 2009

Ваш TestClass нарушает договор Object.Equals. Assert.AreEqual вполне обоснованно полагается на этот контракт.

Состояние документов (в списке требований):

  • x.Equals (пустая ссылка (ничего в Visual Basic)) возвращает false.
5 голосов
/ 20 января 2009

При тестировании на нули не используйте Assert.AreEqual.

Для этого вы должны использовать Assert.IsNull().

1 голос
/ 20 января 2009

Нет, это правильно - вы инициализировали t для нового объекта TestClass, который не равен NULL, поэтому утверждение не выполнено.

1 голос
/ 20 января 2009

Первый тест не пройден. Проверьте, является ли "t" нулевым, а это не так, потому что вы инициализировали t новым объектом TestClass.

Второй тест пройден, потому что t.Equals всегда возвращает true.

Если один тест не пройден, весь TestMethod1 помечается как неудачный.

0 голосов
/ 20 января 2009

Если я вас правильно понял, на самом деле предполагается, что AreEqual(anythingButNull, null) всегда возвращает false?

(правка) Причина, по которой я задумался, заключается в том, что тест для нуля, как того требует контракт Равных, не вызывается при тестировании модуля в классе. Так как AreEqual опирается на контракт, он не может проверить, соответствует ли мой класс контракту. Так что я думаю, что я должен использовать обходной путь Assert.IsFalse(blah.Equals(null)).

...