1. 概要

この短いチュートリアルでは、Mockitoを使用したvoidメソッドのモックに焦点を当てます。

Mockitoフレームワークに焦点を当てた他の記事( Mockito Verification Mockito When / Then MockitoのMockメソッドなど)と同様に、 MyList [以下に示すX170X]クラスは、テストケースの共同作業者として使用されます。

このチュートリアルに新しいメソッドを追加します。

public class MyList extends AbstractList<String> {
 
    @Override
    public void add(int index, String element) {
        // no-op
    }
}

2. 簡単なモックと検証

Void メソッドは、Mockitoの doNothing() doThrow()およびdoAnswer()メソッドで使用できるため、モックと検証が直感的になります。 :

@Test
public void whenAddCalledVerified() {
    MyList myList = mock(MyList.class);
    doNothing().when(myList).add(isA(Integer.class), isA(String.class));
    myList.add(0, "");
 
    verify(myList, times(1)).add(0, "");
}

ただし、 doNothing()は、voidメソッドに対するMockitoのデフォルトの動作です。

このバージョンのwhenAddCalledVerified()は、上記と同じことを実行します。

@Test
public void whenAddCalledVerified() {
    MyList myList = mock(MyList.class);
    myList(0, "");
 
    verify(myList, times(1)).add(0, "");
}

DoThrow()は例外を生成します:

@Test(expected = Exception.class)
public void givenNull_AddThrows() {
    MyList myList = mock(MyList.class);
    doThrow().when(myList).add(isA(Integer.class), isNull());
 
    myList.add(0, null);
}

以下でdoAnswer()について説明します。

3. 引数キャプチャ

doNothing()でデフォルトの動作をオーバーライドする理由の1つは、引数をキャプチャすることです。

上記の例では、 verify()メソッドを使用して、 add()に渡された引数をチェックしました。

ただし、引数をキャプチャして、さらに何かを行う必要がある場合があります。

このような場合、上記と同じように doNothing()を使用しますが、ArgumentCaptorを使用します。

@Test
public void whenAddCalledValueCaptured() {
    MyList myList = mock(MyList.class);
    ArgumentCaptor<String> valueCapture = ArgumentCaptor.forClass(String.class);
    doNothing().when(myList).add(any(Integer.class), valueCapture.capture());
    myList.add(0, "captured");
 
    assertEquals("captured", valueCapture.getValue());
}

4. Voidへの呼び出しに応答する

メソッドは、単に値を追加または設定するよりも複雑な動作を実行する場合があります。

このような状況では、Mockitoの Answer を使用して、必要な動作を追加できます。

@Test
public void whenAddCalledAnswered() {
    MyList myList = mock(MyList.class);
    doAnswer(invocation -> {
        Object arg0 = invocation.getArgument(0);
        Object arg1 = invocation.getArgument(1);
        
        assertEquals(3, arg0);
        assertEquals("answer me", arg1);
        return null;
    }).when(myList).add(any(Integer.class), any(String.class));
    myList.add(3, "answer me");
}

MockitoのJava8機能で説明されているように、 Answer でラムダを使用して、 add()のカスタム動作を定義します。

5. 部分的なモッキング

部分的なモックもオプションです。 MockitoのdoCallRealMethod()は、voidメソッドに使用できます。

@Test
public void whenAddCalledRealMethodCalled() {
    MyList myList = mock(MyList.class);
    doCallRealMethod().when(myList).add(any(Integer.class), any(String.class));
    myList.add(1, "real");
 
    verify(myList, times(1)).add(1, "real");
}

このようにして、実際のメソッドを呼び出し、同時に検証することができます。

6. 結論

この短い記事では、Mockitoでテストするときにvoidメソッドにアプローチする4つの異なる方法について説明しました。

いつものように、例はこのGitHubプロジェクトで利用できます。