NUnit doesn't work well with Assert.AreEqual

c#, nunit, unit-testing

Solution

The problem is you're hiding Equals, not overriding it. Well done - your unit test has found a bug :)

Your code should be:

public override bool Equals(object obj)
{
    Money money = obj as Money;
    if (money == null)
        return false;

    return (amount == money.amount && currency == money.currency);
}

(This will prevent it from throwing an exception if you give it the wrong type, too.)

I've made the string equality test simpler too - operator overloading can be very helpful :)

By the way, you almost certainly want to:

- Change `Currency` to be a property, not a method

- Add an `Amount` property

- Probably change the type of `amount` to be `decimal` instead of `int`

- Make the fields private and readonly

- Seal the class

- Add operator overloads for == and !=

- Possibly add a * operator overload to do the same as `Times`

- Avoid string formatting when calculating the hash (there are dozens of answers showing better hash implementations)

EDIT: I've just reread that you're using an example from a book. Does the book really hide instead of overriding the `Equals` method? I suggest you get a new book, if so (unless it's being a deliberate example of when it's wrong to use hiding!)... which book is it?

Problem

I'm new to unit testing and NUit in particular. I'm just typing some examples from the book which refers to Java and JUnit. But I'm using C# instead. The problem is: I've got a class with overriden methods such as `Equals()` and `GetHashCode()`, but when I am trying to compare two objects of this class with `Assert.AreEqual()` my code is not called, so I get an exception. `Assert.True(MyClass.Equals(MyClass2))` does work well. But I don't want to use this construction instead of `Assert.AreEqual()`. Where can the problem be? Here is the class: ``` public class Money { public int amount; protected string currency; public Money(int amount, string currency) { this.amount = amount; this.currency = currency; } public new bool Equals(object obj) { if (obj == null) return false; Money money = (Money)obj; return (amount == money.amount) && (Currency().Equals(money.Currency())); } public new int GetHashCode() { return (string.Format("{0}{1}", amount, currency)).GetHashCode(); } public static Money Dollar(int amount) { return new Money(amount, "USD"); } public static Money Franc(int amount) { return new Money(amount, "CHF"); } public Money Times(int multiplier) { return new Money(amount * multiplier, currency); } public string Currency() { return currency; } } ``` And the test method itself: ``` [TestFixture] public class DollarTest { [Test] public void TestMultiplication() { Money five = Money.Dollar(5); Assert.True(Money.Dollar(10).Equals(five.Times(2))); // ok Assert.AreEqual(Money.Dollar(10), five.Times(2)); // fails } } ```

Original source