单元测试确保在方法B之后调用方法A.

时间:2012-11-23 15:19:32

标签: unit-testing

我有一个与某个对象交互的代码,然后应该在其上调用finish()方法。

void completeTransaction(PaymentTransaction transaction) {  
    recordTransaction(transaction.getId());

    transaction.finish();
}

PaymentTransaction是一些第三方类,finish()未定义后的行为 - 它可能会抛出异常或者只是静默失败。

我需要编写一个单元测试,然后才通过:

  1. recordTransaction(transaction.getId())名为
  2. transaction.finish()名为
  3. transaction.finish()recordTransaction(transaction.getId())
  4. 之后调用

    满足上述条件的测试应该禁止这样的代码:

    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
    }
    

    我想知道如何通过测试用例强制执行第三个条件。

3 个答案:

答案 0 :(得分:2)

你可以传入一个覆盖PaymentTransactionfinish()的假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);

}