74

私はいくつかのコードを持っています

service.doAction(request, Callback<Response> callback);

Mockito を使用してコールバック オブジェクトを取得し、callback.reply(x) を呼び出すにはどうすればよいですか

4

4 に答える 4

84

Answerそれを行うオブジェクトを設定します。https://static.javadoc.io/org.mockito/mockito-core/2.8.47/org/mockito/Mockito.html#answer_stubsにある Mockito のドキュメントを ご覧ください。

あなたは次のようなものを書くかもしれません

when(mockService.doAction(any(Request.class), any(Callback.class))).thenAnswer(
    new Answer<Object>() {
        Object answer(InvocationOnMock invocation) {
            ((Callback<Response>) invocation.getArguments()[1]).reply(x);
            return null;
        }
});

x(もちろん、あるべきものに置き換えます)

于 2012-11-28T23:56:35.483 に答える
57

ArgumentCaptorの使用を検討してください。これは、いずれの場合も「コールバックオブジェクトを取得する」に近いものです。

/**
 * Captor for Response callbacks. Populated by MockitoAnnotations.initMocks().
 * You can also use ArgumentCaptor.forClass(Callback.class) but you'd have to
 * cast it due to the type parameter.
 */
@Captor ArgumentCaptor<Callback<Response>> callbackCaptor;

@Test public void testDoAction() {
  // Cause service.doAction to be called

  // Now call callback. ArgumentCaptor.capture() works like a matcher.
  verify(service).doAction(eq(request), callbackCaptor.capture());

  assertTrue(/* some assertion about the state before the callback is called */);

  // Once you're satisfied, trigger the reply on callbackCaptor.getValue().
  callbackCaptor.getValue().reply(x);

  assertTrue(/* some assertion about the state after the callback is called */);
}

コールバックがすぐに戻る必要がある場合(読み取り:同期)は良い考えですが、匿名の内部クラスを作成し、必要なデータ型にAnswer要素を安全にキャストしないというオーバーヘッドも発生します。invocation.getArguments()[n]また、Answer内からシステムのプレコールバック状態についてアサーションを作成する必要があります。これは、Answerのサイズと範囲が大きくなる可能性があることを意味します。

代わりに、コールバックを非同期的に処理します。ArgumentCaptorを使用して、サービスに渡されたCallbackオブジェクトをキャプチャします。これで、すべてのアサーションをテストメソッドレベルで作成し、必要に応じて呼び出すreplyことができます。これは、サービスが複数の同時コールバックを担当している場合に特に役立ちます。これは、コールバックが返される順序をより細かく制御できるためです。

于 2012-11-29T04:04:52.970 に答える
3
when(service.doAction(any(Request.class), any(Callback.class))).thenAnswer(
    new Answer() {
    Object answer(InvocationOnMock invocation) {
        Callback<Response> callback =
                     (Callback<Response>) invocation.getArguments()[1];
        callback.reply(/*response*/);
    }
});
于 2012-11-29T00:00:21.977 に答える