142

I recently attempted to use the method Assert.Equals() when writing a new NUnit test. Upon execution this method throws an AssertionException stating that Assert.Equals should not be used for Assertions. This is a bit baffling at first glance. What's going on here?

Odrade
  • 7,409
  • 11
  • 42
  • 65
  • Can you give us some context such as the particular code that this was is in? What type of objects were you comparing, etc. ? – Mike Parkhill Jul 20 '12 at 17:50
  • 9
    Sorry, but I already found the answer to this one. I just asked it so I could post the answer for posterity. The context isn't really important, as you'll see by reading the answer. I'm hoping that this answer will be easily discoverable via web search on the exception message. – Odrade Jul 20 '12 at 17:55

2 Answers2

223

Assert is a static class inheriting from System.Object, as all classes do implicitly in C#. System.Object implements the following method:

static bool Equals(object a, object b)

The methods on Assert which are intended for equality comparison are the Assert.AreEqual() methods. Therefore, calling the Object.Equals() method through the Assert class in a unit test is certainly a mistake. In order to prevent this mistake and avoid confusion, the developers of NUnit have intentionally hidden Object.Equals in the Assert class with an implementation that throws an exception. Here's the implementation:

/// <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");
 }

Of course the exception message itself is confusing, but at least it lets you know you've done something wrong.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Odrade
  • 7,409
  • 11
  • 42
  • 65
  • 19
    The message is confusing, but enter it into Google and you end up right here at this answer and all is well. Thanks Odrade. – Stephen Holt Apr 04 '13 at 15:08
  • 33
    The developers of NUnit could change the message to say "...use Assert.AreEqual()". – WillC Jun 05 '15 at 17:29
  • Why they just didn't made Equals method private instead? – shytikov Jun 09 '15 at 10:18
  • 4
    @shytikov Because that is impossible. You can't override a virtual method from a base class with a private one. – Odrade Jun 30 '15 at 21:01
  • Thanks for the info, Why NUnit developers didnt route `Equals` call to `AreEqual` instead of showing this confusing message.. – arielhad Oct 20 '20 at 07:30
  • Note: now the exception message from NUnit does have new text. It now reads: "Assert.Equals should not be used. Use Assert.AreEqual instead". – topsail Dec 02 '20 at 16:08
24

tldr;

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

not:

Assert.Equals(a, b); // <-- Irrelevant equality operator on Assert itself
Doug
  • 32,844
  • 38
  • 166
  • 222