Mockitovalidation了特定的lambda在mock的方法中作为参数传递
我想测试以下方法:
public void dispatchMessage(MessageHandler handler, String argument1, String argument2, Long argument3) { handler.registerMessage(() -> { dispatcher.dispatch(argument1, argument2, argument3); }); }
其中MessageHandler
是一个辅助类,它将以lambda的forms接受Functional Interface实现,并将其存储以供以后执行。
有没有办法validationmockito已使用特定的lambda表达式调用MessageHandler
的dispatchMessage
方法:
意思是,我可以写一个这样的测试:
@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试图比较function接口的两个不同实现,它们具有不同的哈希码。
那么还有其他方法可以validation方法dispatchMessage()
是否已使用返回void的lambda调用,并且具有dispatcher.dispatch("activityId", "ctxId", 1l,);
的body方法dispatcher.dispatch("activityId", "ctxId", 1l,);
?
是的你可以。 这里的技巧是你必须到达传递给registerMessage
的lambda实例,然后执行该表达式然后你可以validation结果。
出于一个有意义的例子的目的,我创建了这个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表达式只是将函数传递给方法的简单forms。 在此示例中,该函数是Runnable
的run
方法。 因此, MessageHandler
接口的方法registerMessage
将Runnable
作为其参数。 我还包括Dispatcher
的实现,它从registerMessage
调用。 对此的测试如下所示:
@RunWith(MockitoJUnitRunner.class) public class HandlerTest { @Mock private Dispatcher dispatcher; @InjectMocks private Handler classUnderTest; @Captor private ArgumentCaptor 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); } }
我们在registerMessage
的第一次validation中使用了lambda表达式的ArgumentCaptor
。 在validation之后,我们可以从捕获器中检索lambda表达式。 lambda表达式的类型是Runnable
,如MessageHandler
接口中所定义。 因此,我们可以在其上调用run
方法,然后validationDispatcher
上的dispatch
方法是否使用所有适当的参数进行调用。