Mockitoモックメソッド
1. 概要
このチュートリアルでは、Mockito APIの標準の静的mockメソッドのさまざまな使用法について説明します。
Mockitoフレームワーク(Mockito VerifyやMockito When/Thenなど)に焦点を当てた他の記事と同様に、以下に示すMyListクラスは、テストケースでモックされるコラボレーターとして使用されます。
public class MyList extends AbstractList {
@Override
public String get(int index) {
return null;
}
@Override
public int size() {
return 1;
}
}
2. シンプルなモッキング
mockメソッドの最も単純なオーバーロードされたバリアントは、モックされるクラスの単一のパラメーターを持つものです。
public static T mock(Class classToMock)
このメソッドを使用してクラスをモックし、期待値を設定します。
MyList listMock = mock(MyList.class);
when(listMock.add(anyString())).thenReturn(false);
次に、モックでメソッドを実行します。
boolean added = listMock.add(randomAlphabetic(6));
次のコードは、addメソッドがモックで呼び出されたこと、および呼び出しが前に設定した期待値と一致する値を返すことを確認します。
verify(listMock).add(anyString());
assertThat(added, is(false));
3. モックの名前で嘲笑する
このセクションでは、モックの名前を指定する引数が提供されるmockメソッドの別のバリアントについて説明します。
public static T mock(Class classToMock, String name)
一般的に、モックの名前は動作中のコードとは関係ありませんが、モックの名前が検証エラーを追跡するために使用されるデバッグに関しては役立つ場合があります。
提供されたモックの名前が、失敗した検証からスローされた例外のメッセージに含まれていることを確認するために、ExpectedExceptionと呼ばれるTestRuleインターフェイスのJUnit実装に依存し、それを含めます。テストクラスで:
@Rule
public ExpectedException thrown = ExpectedException.none();
このルールは、テストメソッドからスローされた例外を処理するために使用されます。
次のコードでは、MyListクラスのモックを作成し、myMockという名前を付けます。
MyList listMock = mock(MyList.class, "myMock");
その後、モックのメソッドに期待値を設定して実行します。
when(listMock.add(anyString())).thenReturn(false);
listMock.add(randomAlphabetic(6));
モックに関する情報を含むメッセージで例外をスローする必要がある、意図的に失敗した検証を作成します。 そのためには、例外に対する期待を最初に設定する必要があります。
thrown.expect(TooLittleActualInvocations.class);
thrown.expectMessage(containsString("myMock.add"));
次の検証は失敗し、予期されたものと一致する例外をスローする必要があります。
verify(listMock, times(2)).add(anyString());
スローされた例外のメッセージは次のとおりです。
org.mockito.exceptions.verification.TooLittleActualInvocations:
myMock.add();
Wanted 2 times:
at com.example.mockito.MockitoMockTest
.whenUsingMockWithName_thenCorrect(MockitoMockTest.java:...)
but was 1 time:
at com.example.mockito.MockitoMockTest
.whenUsingMockWithName_thenCorrect(MockitoMockTest.java:...)
ご覧のとおり、モックの名前が例外メッセージに含まれています。これは、検証が失敗した場合に障害点を見つけるのに役立ちます。
4. Answerでモックする
ここでは、相互作用に対するモックの回答の戦略が作成時に構成されているmockバリアントの使用方法を示します。 Mockitoドキュメントのこのmockメソッドのシグネチャは、次のようになります。
public static T mock(Class classToMock, Answer defaultAnswer)
Answerインターフェースの実装の定義から始めましょう。
class CustomAnswer implements Answer {
@Override
public Boolean answer(InvocationOnMock invocation) throws Throwable {
return false;
}
}
上記のCustomAnswerクラスは、モックの生成に使用されます。
MyList listMock = mock(MyList.class, new CustomAnswer());
メソッドに期待値を設定しない場合、CustomAnswerタイプで構成されたデフォルトの回答が機能します。 それを証明するために、期待値設定ステップをスキップして、メソッドの実行にジャンプします。
boolean added = listMock.add(randomAlphabetic(6));
次の検証とアサーションは、Answer引数を持つmockメソッドが期待どおりに機能したことを確認します。
verify(listMock).add(anyString());
assertThat(added, is(false));
5. MockSettingsでモックする
この記事で取り上げる最後のmockメソッドは、MockSettingsタイプのパラメーターを持つバリアントです。 このオーバーロードされたメソッドは、非標準のモックを提供するために使用されます。
invocationListenersを使用した現在のモックでのメソッド呼び出しのリスナーの登録、serializableを使用したシリアル化の構成、インスタンスの指定など、MockSettingsインターフェイスのメソッドでサポートされるカスタム設定がいくつかあります。 spiedInstanceでスパイする、useConstructorでモックをインスタンス化するときにコンストラクターを使用しようとするようにMockitoを構成するなど。
便宜上、前のセクションで紹介したCustomAnswerクラスを再利用して、デフォルトの回答を定義するMockSettings実装を作成します。
MockSettingsオブジェクトは、次のようにファクトリメソッドによってインスタンス化されます。
MockSettings customSettings = withSettings().defaultAnswer(new CustomAnswer());
その設定オブジェクトは、新しいモックの作成に使用されます。
MyList listMock = mock(MyList.class, customSettings);
前のセクションと同様に、MyListインスタンスのaddメソッドを呼び出し、MockSettings引数を指定したmockメソッドが意図したとおりに機能することを確認します。次のコードスニペット:
boolean added = listMock.add(randomAlphabetic(6));
verify(listMock).add(anyString());
assertThat(added, is(false));
6. 結論
このチュートリアルでは、Mockitoのmockメソッドについて詳しく説明しました。 これらの例とコードスニペットの実装は、a GitHub projectにあります。