Mockito - スパイを使う

Mockito –スパイの使用

1. 概要

このチュートリアルでは、spies in Mockitoを最大限に活用する方法を説明します。

@Spyアノテーション、スパイをスタブ化する方法について説明し、最後に–MockSpyの違いについて説明します。

そしてもちろん、より多くのMockitoの良さのために、have a look at the series here

参考文献:

Mockito Verify Cookbook

Mockito Verifyの例、使用法、およびベストプラクティス。

MockitoモックをSpring Beanに注入する

この記事では、依存関係注入を使用して、Mockitoモックを単体テスト用のSpring Beanに挿入する方法を示します。

Mockitoモックメソッド

このチュートリアルでは、Mockito APIの標準の静的モックメソッドのさまざまな使用方法を説明します。

2. 単純なSpyの例

how to use a spyの簡単な例から始めましょう。

簡単に言えば、APIはMockito.spy() –からspy on a real objectです。

これにより、モックの場合と同様に、すべてのインタラクションを追跡しながら、オブジェクトのすべての通常のメソッドを呼び出すことができます。

OK、既存のArrayListオブジェクトをスパイする簡単な例を見てみましょう。

@Test
public void whenSpyingOnList_thenCorrect() {
    List list = new ArrayList();
    List spyList = Mockito.spy(list);

    spyList.add("one");
    spyList.add("two");

    Mockito.verify(spyList).add("one");
    Mockito.verify(spyList).add("two");

    assertEquals(2, spyList.size());
}

the real method add() is actually calledspyListのサイズが2になることに注意してください。

3. @Spy注釈

次へ–@Spyアノテーションの使用方法を見てみましょう。 次の例のように、spy()の代わりに@Spyアノテーションを使用できます。

@Spy
List spyList = new ArrayList();

@Test
public void whenUsingTheSpyAnnotation_thenObjectIsSpied() {
    spyList.add("one");
    spyList.add("two");

    Mockito.verify(spyList).add("one");
    Mockito.verify(spyList).add("two");

    assertEquals(2, spyList.size());
}

enable Mockito annotation@Spy@Mock、…など)を実行するには、次のいずれかを実行する必要があります。

  • メソッドMockitoAnnotations.initMocks(this)を呼び出して、注釈付きフィールドを初期化します

  • 組み込みのランナー@RunWith(MockitoJUnitRunner.class)を使用します

4. Spyをスタブする

では、Spyをスタブ化する方法を見てみましょう。 モックで使用するのと同じ構文を使用して、メソッドの動作を構成/オーバーライドできます。

次の例では、doReturn()を使用してsize()メソッドをオーバーライドします。

@Test
public void whenStubASpy_thenStubbed() {
    List list = new ArrayList();
    List spyList = Mockito.spy(list);

    assertEquals(0, spyList.size());

    Mockito.doReturn(100).when(spyList).size();
    assertEquals(100, spyList.size());
}

5. Mock対。 Spy in Mockito

それでは、MockitoのMockSpyの違いについて説明しましょう。2つの概念の理論的な違いではなく、Mockito自体の違いについて説明します。

Mockitoがモックを作成する場合、実際のインスタンスからではなく、タイプのClassから作成します。 モックは、クラスのa bare-bones shell instanceを作成するだけで、クラスとの相互作用を追跡するために完全にインストルメント化されています。

一方、the spy will wrap an existing instance。 まだ通常のインスタンスと同じように動作します-唯一の違いは、それとのすべての相互作用を追跡するために装備されることです。

次の例では、ArrayListクラスのmockを作成します。

@Test
public void whenCreateMock_thenCreated() {
    List mockedList = Mockito.mock(ArrayList.class);

    mockedList.add("one");
    Mockito.verify(mockedList).add("one");

    assertEquals(0, mockedList.size());
}

ご覧のとおり、モックリストに要素を追加しても実際には何も追加されません。メソッドを呼び出すだけで、他の副作用はありません。

一方、スパイの動作は異なります。実際には、addメソッドの実際の実装を呼び出し、その要素を基になるリストに追加します。

@Test
public void whenCreateSpy_thenCreate() {
    List spyList = Mockito.spy(new ArrayList());

    spyList.add("one");
    Mockito.verify(spyList).add("one");

    assertEquals(1, spyList.size());
}

6. MockitoNotAMockExceptionを理解する

この最後のセクションでは、MockitoNotAMockExceptionについて学習します。 This exception is one of the common exceptions we will likely encounter when misusing mocks or spies

この例外が発生する可能性のある状況を確認することから始めましょう。

List list = new ArrayList();
Mockito.doReturn(100).when(list).size();

assertEquals("Size should be 100: ", 100, list.size());

このコードスニペットを実行すると、次のエラーが発生します。

org.mockito.exceptions.misusing.NotAMockException:
Argument passed to when() is not a mock!
Example of correct stubbing:
    doThrow(new RuntimeException()).when(mock).someMethod();

ありがたいことに、Mockitoのエラーメッセージから、ここに問題が何であるかが明確にわかります。 この例では、listオブジェクトはモックではありません。 The Mockito when() method expects a mock or spy object as the argument

また、例外メッセージには、正しい呼び出しがどのように見えるべきかが記載されています。 問題が何であるかをよりよく理解できたので、次の推奨事項に従って修正しましょう。

final List spyList = Mockito.spy(new ArrayList());
Mockito.doReturn(100).when(spyList).size();

assertEquals("Size should be 100: ", 100, spyList.size());

この例は期待どおりに動作し、MockitoNotAMockException.は表示されなくなりました。

7. 結論

この簡単な記事では、Mockitoスパイの最も便利な使用例について説明しました。

spyの作成方法、@Spyアノテーションの使用方法、spyのスタブ方法、そして最後に–MockSpyの違いを学びました。

これらすべての例の実装can be found over on GitHub.

これはMavenプロジェクトであるため、そのままインポートして実行するのは簡単です。

そしてもちろん、より多くのMockitoの良さのために、have a look at the series here