NUnit与Assert.AreEqual不兼容

sta*_*sal 11 c# nunit unit-testing

我是单元测试的新手,尤其是NUit.我只是在本书中输入一些引用Java和JUnit的例子.但我正在使用C#代替.

问题是:我有一个带有覆盖方法的类,例如Equals()GetHashCode(),但是当我试图比较这个类的两个对象时,Assert.AreEqual()我的代码没有被调用,所以我得到一个异常.

Assert.True(MyClass.Equals(MyClass2))确实运作良好.但我不想用这种结构代替Assert.AreEqual().问题出在哪里?

这是班级:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

而测试方法本身:

[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
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 31

问题是你隐藏了 Equals,而不是覆盖它.干得好 - 你的单元测试发现了一个bug :)

你的代码应该是:

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

    return (amount == money.amount && currency == money.currency);
}
Run Code Online (Sandbox Code Playgroud)

(如果你给它错误的类型,这将防止它抛出异常.)

我已经使字符串相等测试更简单 - 运算符重载可能非常有用:)

顺便说一下,你几乎肯定想:

  • 改变Currency是一个属性,而不是方法
  • 添加一个Amount属性
  • 也许改变的类型amountdecimal不是int
  • 将字段设为私有和只读
  • 密封课程
  • 为==和!=添加运算符重载
  • 可能会添加*运算符重载以执行相同操作 Times
  • 在计算哈希时避免字符串格式化(有数十个答案显示更好的哈希实现)

编辑:我刚刚重读你正在使用书中的一个例子.这本书是否真的隐藏而不是覆盖Equals方法?我建议你买一本新书,如果是这样的话(除非它是一个故意的例子,说明什么时候使用隐藏是错误的!)......这本书是哪本书?

  • 希望这个bug证明了单元测试的价值! (2认同)