我有一个与某个对象交互的代码,然后应该在其上调用finish()方法。
void completeTransaction(PaymentTransaction transaction) {
recordTransaction(transaction.getId());
transaction.finish();
}
PaymentTransaction是一些第三方类,finish()
未定义后的行为 - 它可能会抛出异常或者只是静默失败。
我需要编写一个单元测试,然后才通过:
recordTransaction(transaction.getId())
名为transaction.finish()
名为transaction.finish()
在 recordTransaction(transaction.getId())
满足上述条件的测试应该禁止这样的代码:
void completeTransaction(PaymentTransaction transaction) {
transaction.finish();
recordTransaction(transaction.getId()); //oops
}
第一个条件的测试用例:
void testCompleteTransaction_TransactionRecorded() {
completeTransaction(transactionMock);
// assert that recordTransaction(transaction.getId())
// called with correct argument
completeTransaction(PaymentTransaction事务) } 对于第二个:
void testCompleteTransaction_TransactionCompleted() {
completeTransaction(transactionMock);
// assert that transaction.finish() called
}
我想知道如何通过测试用例强制执行第三个条件。
答案 0 :(得分:2)
你可以传入一个覆盖PaymentTransaction
和finish()
的假getId()
,这样finish()
如果在{{1}时未设置某个内部标志,则会引发异常被称为。
getId()
现在,当您将其传递到SUT时,您将看到是否以正确的顺序进行了调用。
答案 1 :(得分:1)
你想要的是一个模拟器,可以验证调用顺序是否符合预期。您可以根据James D'Angelo的回答中的建议为自己的具体案例滚动自己,或者您可以创建一个类似的更通用的案例。
或者您可以使用由良好的模拟框架提供的设施。
例如,Mockito有一个InOrder验证程序,可以验证来自单个模拟或多个模拟的模拟方法的调用顺序。答案 2 :(得分:0)
您的测试用例毫无意义:
按照代码中的顺序调用方法: 在单元测试中,您不仅应该调用某些方法,还应该测试正确的结果。
但如果你想要玩得开心:
public testNonsenseTest() {
int i = 0;
PaymentTransaction transaction = new PaymentTransaction();
int transactionId = transaction.getId());
recordTransaction(transactionId);
i++;
assertEquals(1, i);
transaction.finish();
i++;
assertEquals(2, i);
}