1

我有一个与某个对象交互的代码,然后应该调用它的 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())

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

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 transaction) } 对于第二个:

void testCompleteTransaction_TransactionCompleted() {
    completeTransaction(transactionMock);
    // assert that transaction.finish() called
}

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

4

3 回答 3

2

如果在调用时未设置某些内部标志,您可以传入一个PaymentTransaction覆盖的假文件finish()getId()这样会finish()引发异常。getId()

public class FakePaymentTransaction {
    private bool _getIdWasCalled = false;

    public override void finish () {
        if (!_getIdWasCalled) {
            throw new Exception ("getId wasn't called first!");
        }
    }

    public override /* your return type */ getId() {
        _getIdWasCalled = true;
        // Some other logic to return your specified return type
    }
}

现在,当您将其传递给您的 SUT 时,您将查看调用是否以正确的顺序进行。

于 2012-11-23T16:06:29.577 回答
1

您想要的是一个可以验证调用顺序是否符合预期的模拟。您可以按照 James D'Angelo 的回答中的建议为特定案例推出自己的案例,或者您可以创建一个更通用的类似工作的案例。

或者,您可以使用良好的模拟框架提供的设施。

例如,Mockito 有一个InOrder验证器,它可以验证来自单个模拟或多个模拟的模拟方法的调用顺序。

于 2012-11-23T17:05:21.120 回答
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);

}
于 2012-11-23T16:00:49.023 回答