私はいくつかのコードを持っています
service.doAction(request, Callback<Response> callback);
Mockitoを使用してコールバックオブジェクトを取得し、callback.reply(x)を呼び出す方法
それを行う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
を本来あるべきものに置き換えます)
ArgumentCaptor の使用を検討してください。これは、いずれの場合でも、「コールバックオブジェクトをつかむ[bing]」に近いものです。
_/**
* 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]
から要素を安全にキャストしないというオーバーヘッドももたらします。希望するデータ型に。また、回答内からシステムのコールバック前の状態に関するアサーションを作成する必要があります。つまり、回答のサイズと範囲が拡大する可能性があります。
代わりに、コールバックを非同期的に処理します。ArgumentCaptorを使用して、サービスに渡されるCallbackオブジェクトをキャプチャします。これで、すべてのアサーションをテストメソッドレベルで作成し、選択時にreply
を呼び出すことができます。これは、サービスが複数の同時コールバックを担当する場合に特に役立ちます。コールバックが返される順序をより詳細に制御できるためです。
次のような方法がある場合:-
public void registerListener(final IListener listener) {
container.registerListener(new IListener() {
@Override
public void beforeCompletion() {
}
@Override
public void afterCompletion(boolean succeeded) {
listener.afterCompletion(succeeded);
}
});
}
次に、上記の方法を簡単にモックできる方法に従ってください:-
@Mock private IListener listener;
@Test
public void test_registerListener() {
target.registerListener(listener);
ArgumentCaptor<IListener> listenerCaptor =
ArgumentCaptor.forClass(IListener.class);
verify(container).registerListener(listenerCaptor.capture());
listenerCaptor.getValue().afterCompletion(true);
verify(listener).afterCompletion(true);
}
私はこの解決策を見つけるのに多くの時間を費やしていたので、これが誰かを助けることを願っています
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*/);
}
});