2

2つのメソッドがあり、そのうちの1つは基本的に、ほんの少しの追加処理を伴うもう1つのメソッドのラッパーであるとしましょう。

public class ItemRepositoryImpl implements ItemRepository {

    ...

    @Override
    public void delete(UUID itemID) {

        Item item = findOne(itemID);
        delete(item);
    }

    @Override
    public void delete(Item item) {

        // Do a bunch of stuff that needs a lot of tests run on it, like
        //    deleting from multiple data sources etc
        ...
    }
}

ItemRepositoryImplを部分的にモックし、delete(UUID)が最終的にdelete(Item)を呼び出すことを確認するdelete(UUID)メソッドの単体テストを作成することの何が問題になっていますか?これを行うと、削除メソッドごとに重複するテストをたくさん書く必要がなくなります。

Mockitoでは、次のようなスパイを使用してこのようなテストを実装できます。

ItemRepository spyRepo = spy(repository);       // Create the spy
when(spyRepo.findOne(itemID)).thenReturn(item); // Stub the findOne method
doNothing().when(spyRepo).delete(item);         // Stub the delete(Item) method
spyRepo.delete(itemID);                         // Call the method under test

// Verify that the delete(Item) method was called
verify(spyRepo).delete(item);

ただし、Mockitoのドキュメントでは、このタイプの部分的なモックの使用を強く推奨しておらず、基本的には、暫定的なレガシーコードとサードパーティのAPIでのみ使用する必要があると述べています。より良い解決策は何でしょうか?

4

1 に答える 1

1

純粋な単体テストを実行していて、単体テストがメソッドである場合、ここでモックしたものに問題はないと言えます。単体テストはよりブラックボックスのアプローチを取るべきであり、メソッド呼び出しをモックすることによって、テストはテスト対象のメソッドの実装についてあまりにも多くを知っていると主張する人もいます。

テスト対象のユニットがメソッドではなくクラスである場合は、他のクラスへの呼び出しをモックするだけで済みます。

ユニットテストについては常に議論があります。これはあなたの質問に非常に関連する主題に関する興味深い記事です:http://martinfowler.com/articles/mocksArentStubs.html

于 2012-08-24T21:18:04.910 に答える