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) } 2 つ目の場合:

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

テストケースを介して3番目の条件をどのように強制できるのだろうか。

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 に答える