使用 Mockito 调用回调
我有一些代码
service.doAction(request, Callback<Response> callback);
如何使用Mockito抓取回调对象,并调用回调.reply(x)
我有一些代码
service.doAction(request, Callback<Response> callback);
如何使用Mockito抓取回调对象,并调用回调.reply(x)
您希望设置一个执行此操作的对象。看看Mockito文档,在 https://static.javadoc.io/org.mockito/mockito-core/2.8.47/org/mockito/Mockito.html#answer_stubsAnswer
你可以写这样的东西
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,它在任何情况下都与“grab[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 */);
}
虽然当回调需要立即返回(读取:同步)时,an 是一个好主意,但它也引入了创建匿名内部类的开销,并且不安全地将元素从转换为所需的数据类型。它还要求您从答案中对系统的预回调状态进行任何断言,这意味着您的答案的大小和范围可能会增加。Answer
invocation.getArguments()[n]
相反,请异步处理回调:使用 ArgumentCaptor 捕获传递给服务的回调对象。现在,您可以在测试方法级别进行所有断言,并在选择时进行调用。如果您的服务负责多个并发回调,这将特别有用,因为您可以更好地控制回调返回的顺序。reply