我想测试以下方法:
public void dispatchMessage(MessageHandler handler, String argument1, String argument2, Long argument3) {
handler.registerMessage(() -> {
dispatcher.dispatch(argument1,
argument2,
argument3);
});
}
其中MessageHandler
是一个辅助类,它将接受一个lambda形式的功能接口实现,并将其存储起来供以后执行。
有没有办法验证mockito是否使用特定的lambda表达式调用了模拟dispatchMessage
的{{1}}方法:
意思是,我可以写一个这样的测试:
MessageHandler
此测试将导致断言错误: 争论是不同的!通缉:
@Test
public void testDispatchMessage_Success() throws Exception {
myMessageDispatcher.dispatchMessage(handler, "activityId", "ctxId", 1l, );
verify(handler, times(1)).dispatchMessage(() -> {
dispatcher
.dispatch("activityId", "ctxId", 1l,);
});
}
}
实际调用有不同的参数:
......Tests$$Lambda$28/379645464@48f278eb
这是有道理的,因为mockito试图比较功能接口的两个不同实现,它们具有不同的哈希码。
还有其他方法来验证方法..........Lambda$27/482052083@2f217633
是否已使用返回void的lambda调用,并且具有body方法
dispatchMessage()
?
答案 0 :(得分:17)
是的,你可以。这里的诀窍是你必须到达传递给registerMessage
的lambda实例,然后执行该表达式,然后你可以验证结果。
为了一个有意义的例子,我创建了这个Handler
类,其中包含您要测试的dispatchMessage
:
public class Handler {
private Dispatcher dispatcher = new Dispatcher();
public void dispatchMessage(MessageHandler handler, String argument1, String argument2, Long argument3) {
handler.registerMessage(() -> {
dispatcher.dispatch(argument1,
argument2,
argument3);
});
}
interface MessageHandler {
void registerMessage(Runnable run);
}
static class Dispatcher {
void dispatch(String a, String b, long c){
// Do dispatch
}
}
}
你必须记住的是,lambda表达式只是将函数传递给方法的简单形式。在此示例中,函数是run
的{{1}}方法。因此,Runnable
接口的方法registerMessage
会将MessageHandler
作为其参数。
我还包含Runnable
的实现,该实现从Dispatcher
内调用。
对此的测试如下:
registerMessage
我们在@RunWith(MockitoJUnitRunner.class)
public class HandlerTest {
@Mock
private Dispatcher dispatcher;
@InjectMocks
private Handler classUnderTest;
@Captor
private ArgumentCaptor<Runnable> registerMessageLambdaCaptor;
@Test
public void shouldCallDispatchMethod() {
final String a = "foo";
final String b = "bar";
final long c = 42L;
MessageHandler handler = mock(MessageHandler.class);
classUnderTest.dispatchMessage(handler, a, b, c);
verify(handler).registerMessage(registerMessageLambdaCaptor.capture());
Runnable lambda = registerMessageLambdaCaptor.getValue();
lambda.run();
verify(dispatcher).dispatch(a, b, c);
}
}
的第一次验证中使用lambda表达式ArgumentCaptor
。在验证之后,我们可以从捕获者中检索lambda表达式。 lambda表达式的类型为registerMessage
,如Runnable
接口中所定义。因此,我们可以在其上调用MessageHandler
方法,然后验证run
上的dispatch
方法是否已使用所有适当的参数进行调用。
答案 1 :(得分:0)
在特定的lambda之外,您可以验证是否使用 any 这样的lambda表达式调用了您的方法,如下所示:
verify(handler).registerMessage(any())
private fun <T> any(): T {
Mockito.any<T>()
return null as T
}