Mockito 验证特定的 lambda 是否已作为 mock 方法中的参数传递



我想测试以下方法:

public void dispatchMessage(MessageHandler handler, String argument1, String argument2, Long argument3) {
handler.registerMessage(() -> {
dispatcher.dispatch(argument1,
argument2,
argument3);
});
}

其中,MessageHandler是一个助手类,它将接受lambda形式的函数接口实现,并将其存储以供以后执行。

有没有一种方法可以用mockito验证模拟MessageHandlerdispatchMessage方法已经用特定的lambda表达式调用:

意思是,我能写这样一个测试吗:

@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

实际调用有不同的参数:

..........Lambda$27/482052083@2f217633

这是有道理的,因为mockito试图比较函数接口的两种不同实现,它们具有不同的哈希代码。

那么,是否有其他方法可以验证方法dispatchMessage()是否已被lambda调用,该lambda返回void并具有dispatcher.dispatch("activityId", "ctxId", 1l,);

可以。这里的技巧是,您必须找到传递给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表达式只是将函数传递给方法的一种简短形式。在本例中,函数是Runnablerun方法。因此,MessageHandler的接口的方法registerMessage采用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,我们在registerMessage的第一次验证中使用它。验证之后,我们可以从捕获器中检索lambda表达式。lambda表达式的类型是Runnable,如MessageHandler接口中所定义的。因此,我们可以在其上调用run方法,然后验证是否使用所有适当的参数调用了Dispatcher上的dispatch方法。

您想要评估lambdaargThat(a -> a.get(),然后比较它的值:

when(dogObject.barkAt(argThat(a -> a.get().equals(PEOPLE_TO_BARK_AT)))).thenReturn(OUTCOME);

在特定lambda之外,您可以验证您的方法是否是用调用的。任何lambda表达式都是这样调用的:

verify(handler).registerMessage(any())
private fun <T> any(): T {
Mockito.any<T>()
return null as T
}

相关内容

  • 没有找到相关文章

最新更新