NUnit's Assert.Equals zgłasza wyjątek „Assert.Equals nie powinny być używane dla asercji”

134

Niedawno próbowałem użyć metody Assert.Equals () podczas pisania nowego testu NUnit. Po wykonaniu tej metody rzuca AssertionExceptionstwierdzenie, że Assert.Equals should not be used for Assertions. na pierwszy rzut oka jest to nieco zaskakujące. Co tu się dzieje?

Odrade
źródło
Czy możesz podać nam kontekst, na przykład konkretny kod, w którym to się znajduje? Jakie typy obiektów porównywałeś itp.?
Mike Parkhill,
9
Przepraszam, ale już znalazłem odpowiedź na to. Po prostu zapytałem o to, abym mógł opublikować odpowiedź dla potomności. Kontekst nie jest naprawdę ważny, o czym przekonasz się czytając odpowiedź. Mam nadzieję, że tę odpowiedź będzie można łatwo znaleźć za pomocą wyszukiwania w Internecie w komunikacie o wyjątku.
Odrade

Odpowiedzi:

201

Assertjest klasą statyczną dziedziczącą po System.Object, tak jak wszystkie klasy robią to niejawnie w C #. System.Object implementuje następującą metodę:

static bool Equals(object a, object b)

Metody na Assert, które są przeznaczone do porównania równości, są Assert.AreEqual()metodami. Dlatego wywołanie Object.Equals()metody za pomocą klasy Assert w teście jednostkowym jest z pewnością błędem. Aby zapobiec temu błędowi i uniknąć nieporozumień, twórcy NUnit celowo ukryli Object.Equalsw klasie Assert implementację, która zgłasza wyjątek. Oto implementacja:

/// <summary>
 /// The Equals method throws an AssertionException. This is done
 /// to make sure there is no mistake by calling this function.
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 [EditorBrowsable(EditorBrowsableState.Never)]
 public static new bool Equals(object a, object b)
 {
     // TODO: This should probably be InvalidOperationException
     throw new AssertionException("Assert.Equals should not be used for Assertions");
 }

Oczywiście sam komunikat o wyjątku jest mylący, ale przynajmniej informuje Cię, że zrobiłeś coś złego.

Odrade
źródło
13
Wiadomość jest myląca, ale wprowadź ją do Google, a otrzymasz tę odpowiedź i wszystko jest w porządku. Dzięki, Odrade.
Stephen Holt
27
Twórcy NUnit mogli zmienić komunikat na „... użyj Assert.AreEqual ()”.
WillC
Dlaczego po prostu nie ustawili metody Equals jako prywatną?
shytikov
4
@shytikov Ponieważ to niemożliwe. Nie można zastąpić metody wirtualnej z klasy bazowej metodą prywatną.
Odrade
Dzięki za informację, dlaczego programiści NUnit nie przekierowali Equalspołączenia AreEqualzamiast wyświetlać tę mylącą wiadomość ...
arielhad
20

tldr;

Assert.AreEqual(a, b); // <-- Compares a, b

nie:

Assert.Equals(a, b); // <-- Irrelevant equality operator on Assert itself
Doug
źródło