Mockitoでコールバックをテストする

Mockitoを使用したコールバックのテスト

1. 概要

この短いチュートリアルでは、一般的なテストフレームワークMockitoを使用してhow to test Callbacksに焦点を当てます。

2つのソリューション、firstly using an ArgumentCaptor and then the intuitive doAnswer() methodについて説明します。

Mockitoを使用したテストの詳細については、Mockitoシリーズhereを確認してください。

2. コールバックの概要

A callback is a piece of code that is passed as an argument to a method, which is expected to call back (execute) the argument at a given time

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

コールバックを使用する一般的なシナリオはduring service interactions when we need to process the response from a service callです。

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

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

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

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

2.1. シンプルなサービス

また、単純なservice example to demonstrate how to pass and invoke the callbackを使用します。

public void doAction() {
    service.doAction("our-request", new Callback() {
        @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.doActioncall could also be written more conciselyを使用することを選択しました。

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

ラムダ式の詳細については、hereを参照してください。

3. ArgumentCaptorの使用

それでは、how we use Mockito to grab the Callback object using an*ArgumentCaptor*:を見てみましょう。

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

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

    Callback 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 を作成します。 This is simply a wrapper to our Simple Service doAction method callは、コールバックを呼び出す場所です。

次に、最初の引数としてanyString()callbackCaptor.capture() as the second, which is where we capture the Callback objectを渡して、モックサービスインスタンスでdoAction が呼び出されたことを確認します。 次に、getValue()メソッドを使用して、取得した引数の値を返すことができます。

Callbackオブジェクトを取得したので、call the reply method directly and assert that the response data has the correct valueの前にデフォルトで有効なResponseオブジェクトを作成します。

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

次に、MockitoのAnswer object and doAnswer method to stub the void methoddoAction:を使用してcommon solution for stubbing methods that have callbacksを確認します。

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

    doAnswer((Answer) invocation -> {
        Callback 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オブジェクトを作成します。これは、後でテストで使用されます。

次に、モックサービスにAnswerを設定して、doActionが呼び出されたときに、we intercept the invocation and grab the method arguments using invocation.getArgument(1)Callback引数を取得するようにします。

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

スタブvoidメソッドの詳細については、hereを参照してください。

3. 結論

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

いつものように、例はこのGitHub projectで利用できます。