我想知道是否有任何“标准”方法可以确保方法不会修改作为参数传递给它的任何对象。例如:
public void addMoney(Money moneyToAdd) {
if(this.getCurrency().equals(moneyToAdd.getCurrency()){
this.setAmount(this.getAmount() + moneyToAdd.getAmount());
moneyToAdd.setAmount(this.getAmount()); // This is wrong!
} else {
throw new MoneyException(“Cannot add money with different currencies”)
}
}
这显然不是预期的行为,但我不确定如何针对此类问题进行单元测试(甚至不确定是否有必要)。以下是我通常会为此方法编写的案例。
@Before
public void prepareObjects(){
Money gbpMoney1 = New Money(1.0,”GBP”);
Money gbpMoney2 = New Money(2.0,”GBP”);
Money euroMoney = New Money(1.0,”EUR”);
}
@Test
public void addMoneyWithSameCurrencyTest(){
gbpMoney1.add(gbpMoney2);
assertEquals(“Final amount is wrong”,3.0,gbpMoney1.getAmount());
}
@Test(expected = MoneyException.class)
public void addMoneyWithDifferentCurrencyTest(){
gbpMoney1.add(euroMoney);
}
我知道我可能会断言该对象与每次测试方法执行时的对象相同,但这是最好的方法吗?
答案 0 :(得分:2)
使用模拟框架。
EasyMock中的一个例子如下:
@Test
public void thatMoneyAddedIsNotAltered(){
Money mockMoney = EasyMock.createMock(Money.class);
EasyMock.expect( mockMoney.getCurrency() ).andReturn( "EUR" );
EasyMock.expect( mockMoney.getAmount() ).andReturn( 3.0 );
EasyMock.replay(mockMoney);
Money realMoney = new Money();
realMoney.addMoney( mockMoney );
EasyMock.verify( mockMoney );
}
仅期望getAmount
和getCurrency
方法意味着当调用这些方法时,它们将按照您期望的方式运行。 (即返回EUR& 3.0)还有一种隐含的期望,即这些调用只会发生一次。
对EasyMock.verify()
的调用将确保没有其他方法调用您提供的模拟,从而确保您所期望的功能。
有关Java中模拟框架的更多信息,请参阅this article