我正在学习Kent Beck的《测试驱动开发》这本书,作为一项学术练习,但是我使用MSpec来编写测试。在跟随实际例子时,我喜欢引入一些变化,以便我不能简单地把文字复制下来,我发现这样做我倾向于遇到问题并解决它们,从而学到更多知识。我相信这是其中一个场合。
我已经完成了Kent 'money'示例的部分内容。这是我拥有的类结构: 我有以下两个测试环境:
平等被定义为数值和货币相同;对象的实际类型应该被忽略,因此预期的结果是,如果我使用Money或Franc对象测试平等性,只要金额和货币字段相同,就不应该有任何影响。然而,事情并没有按计划进行。调试时,我的Equals()方法甚至没有被调用。显然,我在这里有些东西没有理解。我确信当我知道解决方案时,它会变得非常明显,但我看不到它。有人能提供建议,告诉我需要做什么才能使这个工作吗?
下面是Equals()的实现:
我已经完成了Kent 'money'示例的部分内容。这是我拥有的类结构: 我有以下两个测试环境:
[Subject(typeof(Money), "Equality")]
public class when_comparing_different_classes_for_equality
{
Because of = () => FiveFrancs = new Franc(5, "CHF");
It should_equal_money_with_currency_set_to_francs = () => FiveFrancs.Equals(new Money(5, "CHF")).ShouldBeTrue();
static Franc FiveFrancs;
}
[Subject(typeof(Franc), "multiplication")]
public class when_multiplying_a_franc_amount_by_an_integer
{
Because of = () => FiveFrancs = new Franc(5, null);
It should_be_ten_francs_when_multiplied_by_2 = () => FiveFrancs.Times(2).ShouldEqual(Money.Franc(10));
It should_be_fifteen_francs_when_multiplied_by_3 = () => FiveFrancs.Times(3).ShouldEqual(Money.Franc(15));
static Franc FiveFrancs;
}
Times()方法返回一个新的Money类型对象,其中包含结果,即这些对象是不可变的。第一个上下文通过了,表明Equals方法按预期工作,即它忽略对象类型,只要它们都继承自Money,并且仅比较金额和货币字段是否相等。第二个上下文失败,输出类似于以下内容:
Machine.Specifications.SpecificationException
Expected: TDDByExample.Money.Specifications.Franc:[15]
But was: TDDByExample.Money.Specifications.Money:[15]
at TDDByExample.Money.Specifications.when_multiplying_a_franc_amount_by_an_integer.<.ctor>b__2() in MoneySpecs.cs: line 29
平等被定义为数值和货币相同;对象的实际类型应该被忽略,因此预期的结果是,如果我使用Money或Franc对象测试平等性,只要金额和货币字段相同,就不应该有任何影响。然而,事情并没有按计划进行。调试时,我的Equals()方法甚至没有被调用。显然,我在这里有些东西没有理解。我确信当我知道解决方案时,它会变得非常明显,但我看不到它。有人能提供建议,告诉我需要做什么才能使这个工作吗?
下面是Equals()的实现:
public bool Equals(Money other)
{
return amount == other.amount && currency == other.currency;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
return false;
if (ReferenceEquals(this, obj))
return true;
return Equals(obj as Money);
}