NUnit测试Bug?预期的<mytype>但是<mytype> </mytype> </mytype>

时间:2012-10-22 15:12:42

标签: c# unit-testing nunit

[Test]
public void testMultiplication()
{
    var five=new Dollar(5);
    Assert.AreEqual(new Dollar(10), five.times(2));
    Assert.AreEqual(new Dollar(15), five.times(3));
}

美元等级

public class Dollar
{
    private int amount;

    public Dollar(int amount)
    {
        this.amount = amount;
    }

    public Dollar times(int multiplier)
    {
        return new Dollar(amount * multiplier);
    }

    public bool equals(Object theObject)
    {
       Dollar dollar = (Dollar) theObject;

       return amount == dollar.amount;
    }
}

在线Assert.AreEqual(新元(10),五次(2));测试失败并出现错误:

预计:TDDbooks.Dollar

但是:TDDbooks.Dollar

5 个答案:

答案 0 :(得分:11)

Assert.AreEquals方法将使用Equals方法来测试相等性。 {1}}类型不是覆盖Object.Equals,而是定义一个不参与.Net对象相等的新Dollar方法。因此它没有被使用,测试使用失败的引用相等。要解决此问题,您需要覆盖equals方法

Object.Equals

答案 1 :(得分:4)

NUnit显示对象的字符串表示形式。为了获得方便的输出,您应该覆盖ToString类的Dollar方法:

public override string ToString()
{
   return "$" + amount;
}

现在输出将如下:

Expected: $10 
But was: $10

下一个问题是美元比较。 NUnit通过调用Equals方法(不是equals,而是Equals来比较对象.Kent Beck在他的示例中使用Java。在C#中,我们使用Pascal命名方法)。如果对象具有相同的引用,则Equals方法的默认实现返回true。但是在Times方法中,您创建了Dollar类的新实例。为了解决这个问题,您应该更改Equals方法实现以比较金额字段。

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

  return amount == other.amount;
}

另请注意,您应该使用override关键字来覆盖基类功能。还有一件事 - 当您覆盖Equals功能时,您应该覆盖GetHashCode方法。在你的情况下,可以使用以下内容:

public override int GetHashCode()
{
  return amount.GetHashCode();
}

答案 2 :(得分:0)

有几件事:

  1. 您已经定义了一个新方法equals,而不是覆盖基类方法Equals。切换到覆盖,NUnit将调用您的方法。
  2. NUnit使用其ToString打印出对象,而ToString的默认实现是简单地打印类名。覆盖ToString以打印金额,断言消息将更有意义。

答案 3 :(得分:0)

你断言的是new Dollar(10)five.times(2)返回的对象是同一个对象,但这不是真的。

如果你想以这种方式断言,你需要像你这样在你的Dollar类中重载Equals方法:

 public override bool Equals(Object obj)
 {
     if (obj is Dollar)
     {
         return this.Amount == ((Dollar)obj).Amount;
     }
     return false;
 }

您未在override方法中使用Equals关键字。

答案 4 :(得分:0)

最好的解决方案已由少数人提供,但有一种替代方案可能适用于其他情况。您需要为amount字段添加一个getter,如下所示:

public int Amount { get { return amount; } }

然后当你进行单元测试时,它看起来像:

Assert.AreEqual(10, five.times(2).Amount);

现在您要将int与另一个int进行比较。或者,您可以将amount变量公开,但这会破坏封装。在这种情况下,显然正确使用Equals方法是更好的方法,但在某些情况下,这可能更合适。