Recently I discovered quite a handy feature of EasyMock’s IExpectationSetters andReturn method. You are able to chain the return values so that you can return different values each time that expectation is called.
It becomes useful if you consider the following method, where Voucher is an object that cannot be instantiated and needs to be mocked:
public class VoucherHelper
{
public static boolean isVoucherExpired(Voucher voucher)
{
boolean expiredVoucher = true;
Date expiryDate = voucher.getExpiryDate();
if (expiryDate != null)
{
Date now = new Date();
expiredVoucher = now.after(expiryDate);
}
return expiredVoucher;
}
}
To test this method, there are 3 tests that need to be done.
- expiryDate returning null
- expiryDate returning an earlier date than the current date
- expiryDate returning a later date than the current date
This can all be done in one expectation line by chaining the ‘andReturn’ of the expectation.
@Test
public final void testIsVoucherExpired()
{
Voucher voucher = createMock(Voucher.class);
Calendar expiredDate = Calendar.getInstance();
// Make it expired by taking a year off
expiredDate.set(Calendar.YEAR, expiredDate.get(Calendar.YEAR) - 1);
Calendar notExpired = Calendar.getInstance();
// Make it not expired by adding a year
notExpired.set(Calendar.YEAR, notExpired.get(Calendar.YEAR) + 1);
// Test with date returning null, then returning expired, then returning not expired
expect(voucher.getExpiryDate())
.andReturn(null)
.andReturn(expiredDate.getTime())
.andReturn(notExpired.getTime());
replayAll();
assertTrue(VoucherHelper.isVoucherExpired(voucher));
assertTrue(VoucherHelper.isVoucherExpired(voucher));
assertFalse(VoucherHelper.isVoucherExpired(voucher));
verifyAll();
}
EasyMock also allows chaining on the times method and the andThrow method, and all can be used at the same time if you wanted.
expect(voucher.getExpiryDate()) .andReturn(null).times(2) .andThrow(new RuntimeException()) .andReturn(new Date()).times(3);

