Junit测试并确保没有对对象进行不必要的更改

时间:2014-02-14 13:57:22

标签: java junit

我想知道是否有任何“标准”方法可以确保方法不会修改作为参数传递给它的任何对象。例如:

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);
}

我知道我可能会断言该对象与每次测试方法执行时的对象相同,但这是最好的方法吗?

1 个答案:

答案 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 );
}

仅期望getAmountgetCurrency方法意味着当调用这些方法时,它们将按照您期望的方式运行。 (即返回EUR& 3.0)还有一种隐含的期望,即这些调用只会发生一次。

EasyMock.verify()的调用将确保没有其他方法调用您提供的模拟,从而确保您所期望的功能。

有关Java中模拟框架的更多信息,请参阅this article

Java中有许多库提供模拟,例如:EasyMockMockitoJMock