1. 概要

この短いチュートリアルでは、一般的なテストフレームワークMockitoを使用してコールバックをテストする方法に焦点を当てます。

2つのソリューションを検討します。最初にArgumentCaptorを使用し、次に直感的なdoAnswer()メソッドを使用します。

Mockitoを使用したテストの詳細については、Mockitoシリーズこちらをご覧ください。

2. コールバックの概要

コールバックは、メソッドに引数として渡されるコードの一部であり、指定された時間に引数をコールバック(実行)することが期待されます

この実行は、同期コールバックの場合のように即時に実行される場合がありますが、より一般的には、非同期コールバックの場合のように後で発生する場合があります。

コールバックを使用する一般的なシナリオは、サービスコールからの応答を処理する必要がある場合のサービスインタラクション中です。

このチュートリアルでは、テストケースの共同作業者として以下に示すServiceインターフェイスを使用します。

public interface Service {
    void doAction(String request, Callback<Response> callback);
}

Callback 引数では、 reply(T response)メソッドを使用して応答を処理するクラスを渡します。

public interface Callback<T> {
    void reply(T response);
}

2.1. シンプルなサービス

また、簡単なサービスの例を使用して、コールバックを渡して呼び出す方法を示します。

public void doAction() {
    service.doAction("our-request", new Callback<Response>() {
        @Override
        public void reply(Response response) {
            handleResponse(response);
        }
    });
}

handleResponse メソッドは、 Response オブジェクトにデータを追加する前に、応答が有効かどうかを確認します。

private void handleResponse(Response response) {
    if (response.isValid()) {
        response.setData(new Data("Successful data response"));
    }
}

わかりやすくするために、Java Lamda式を使用しないことを選択しましたが、 service.doAction 呼び出しをより簡潔に記述することもできます

service.doAction("our-request", response -> handleResponse(response));

ラムダ式の詳細については、こちらをご覧ください。

3. ArgumentCaptorの使用

次に、 Mockitoを使用して、 ArgumentCaptor:を使用してCallbackオブジェクトを取得する方法を見てみましょう。

@Test
public void givenServiceWithValidResponse_whenCallbackReceived_thenProcessed() {
    ActionHandler handler = new ActionHandler(service);
    handler.doAction();

    verify(service).doAction(anyString(), callbackCaptor.capture());

    Callback<Response> callback = callbackCaptor.getValue();
    Response response = new Response();
    callback.reply(response);

    String expectedMessage = "Successful data response";
    Data data = response.getData();
    assertEquals(
      "Should receive a successful message: ", 
      expectedMessage, data.getMessage());
}

この例では、このハンドラーの doAction メソッドを呼び出す前に、まずActionHandlerを作成します。 これは、コールバックを呼び出す場所であるSimpleServicedoActionメソッドcallの単なるラッパーです。

次に、 doAction がモックサービスインスタンスで呼び出され、最初の引数として anyString()を渡し、2番目の引数として callbackCaptor.capture()を渡したことを確認します。コールバックオブジェクトをキャプチャします。 次に、 getValue()メソッドを使用して、キャプチャされた引数の値を返すことができます。

Callback オブジェクトを取得したので、デフォルトで有効な Response オブジェクトを作成してから、 replyメソッドを直接呼び出し、応答データに正しい値

4. doAnswer()メソッドの使用

次に、MockitoのAnswerオブジェクトとdoAnswerメソッドを使用してvoidメソッド doAction:を使用して、コールバックを持つスタブメソッドの一般的なソリューションを見ていきます。

@Test
public void givenServiceWithInvalidResponse_whenCallbackReceived_thenNotProcessed() {
    Response response = new Response();
    response.setIsValid(false);

    doAnswer((Answer<Void>) invocation -> {
        Callback<Response> callback = invocation.getArgument(1);
        callback.reply(response);

        Data data = response.getData();
        assertNull("No data in invalid response: ", data);
        return null;
    }).when(service)
        .doAction(anyString(), any(Callback.class));

    ActionHandler handler = new ActionHandler(service);
    handler.doAction();
}

そして、2番目の例では、最初に無効な Response オブジェクトを作成します。これは、後でテストで使用されます。

次に、 答え私たちの模擬サービスで doAction と呼ばれる、 呼び出しをインターセプトし、invocation.getArgument(1)を使用してメソッド引数を取得します取得するには折り返し電話口論 。 

最後のステップは、 ActionHandler を作成し、 doAction を呼び出すことです。これにより、Answerが呼び出されます。

スタブボイドメソッドの詳細については、こちらをご覧ください。

3. 結論

この短い記事では、Mockitoでテストするときにコールバックのテストにアプローチする2つの異なる方法について説明しました。

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