NUnit 与 Assert.AreEqual 不能很好地配合
我是单元测试的新手,尤其是 NIt。 我只是从书中输入一些涉及 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;
}
}
以及测试方法本身:
[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
}
}
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
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题是您隐藏 Equals,而不是覆盖它。干得好 - 你的单元测试发现了一个错误:)
你的代码应该是:(
如果你给它错误的类型,这也将防止它抛出异常。)
我也使字符串相等测试更简单 - 运算符重载可能会非常有帮助:)
顺便说一句,您几乎肯定希望:
Currency
更改为属性,而不是方法Amount
属性Amount
的类型code>amount 为decimal
而不是int
Times
相同的操作编辑:我刚刚重读您正在使用书中的示例。这本书真的隐藏而不是重写
Equals
方法吗?如果是的话,我建议你买一本新书(除非它是一个故意的例子,说明什么时候使用隐藏是错误的!)...是哪本书?The problem is you're hiding Equals, not overriding it. Well done - your unit test has found a bug :)
Your code should be:
(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:
Currency
to be a property, not a methodAmount
propertyamount
to bedecimal
instead ofint
Times
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?我发现实现 IEquatable 接口(它也有一个
方法)给我带来了与上述相同的问题,这令人困惑。
我选择使用上面的 IEquaytable 接口覆盖 Equals 方法的唯一原因是不必进行类型检查。
最后我不得不使用下面的代码
,但后来我想,为什么不保留 IEquatable 接口的原样,而只重写 Equals 方法。 (更少的代码=更好)
I found it confusing that implementing the IEquatable interface, which also has an
method, posed me with the same problem as described above.
The only reason I chose to use the IEquaytable interface above overriding the Equals method was not to have to do the type check.
In the end I had to use the following code
but then I thought, why not just leave the IEquatable interface for what it is and only override the Equals method. (less code = better)
我怀疑你的问题是你没有
overridden重载 equal == 运算符。在幕后 Assert.AreEqual 可能使用 ==。请参阅运算符重载教程。
更新:我通过调试器运行了 NUnit 测试,它确实使用了 Equals 方法而不是 == 运算符。
I suspect your problem is that you haven't
overriddenoverload the equality == operator. Under the hood the Assert.AreEqual is probably using ==.See Operator Overloading Tutorial.
Update: I ran the NUnit test through the debugger and it does indeed use the Equals method and not the == operator.
您可以使用名为 Should 的库编写与框架无关的断言。它还具有非常好的流畅语法,如果您喜欢流畅的界面,可以使用它。我有一篇与此相关的博客文章。
http://nileshgule.blogspot.com/2010 /11/use-should-assertion-library-to-write.html
You can write framework agnostic asserts using a library called Should. It also has a very nice fluent syntax which can be used if you like fluent interfaces. I had a blog post related to the same.
http://nileshgule.blogspot.com/2010/11/use-should-assertion-library-to-write.html