当前位置: 首页 > 面试题库 >

Mockito验证特定的lambda已作为模拟方法中的参数传递

梁学真
2023-03-14
问题内容

我想测试以下方法:

    public void dispatchMessage(MessageHandler handler, String argument1, String argument2, Long argument3) {

    handler.registerMessage(() -> {
        dispatcher.dispatch(argument1,
                argument2,
                argument3);
    });

}

MessageHandler帮助器类在哪里,该类将接受lambda形式的Functional Interface实现,并将其存储以供以后执行。

有没有一种方法可以通过mockito验证是否已使用特定的lambda表达式调用了模拟dispatchMessage方法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

实际调用有不同的参数:

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

这是有道理的,因为Mockito尝试比较功能接口的两个不同实现,它们具有不同的哈希码。

那么,是否有其他方法可以验证该方法dispatchMessage()是否已使用返回空值且具有body方法的lambda进行调用
dispatcher.dispatch("activityId", "ctxId", 1l,);


问题答案:

是的你可以。这里的窍门是,您必须到达传递给的lambda实例,registerMessage然后执行该表达式,然后才能验证结果。

为了一个有意义的示例,我创建了一个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方法Runnable。因此,用于registerMessage的接口方法MessageHandler将a
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);
    }
}

有一个ArgumentCaptorlambda表达式供我们在的第一次验证中使用registerMessage。验证之后,我们可以从捕获程序中检索l​​ambda表达式。lambda表达式的类型为Runnable,如MessageHandler接口中所定义。因此,我们可以run在其上调用该方法,然后验证是否已使用所有适当的参数调用dispatch上的方法Dispatcher



 类似资料:
  • 我正在尝试模拟我与外部API的交互,该API检查令牌以查看用户是否有权执行某些操作(它目前是一个单独的API作为PoC,稍后将移动到中间件中) 受抚养人(SBT DSL) 测试 代码 代码使用了一个MyHandler类,该类扩展了trait : 错误 当我运行代码时,我看到以下错误: 我如何确保我可以: a)将身份验证代码移动到MyHandler中,并使用Specs2提供的Mockito对MyHa

  • 问题内容: 我正在尝试测试服务类,该服务类在内部使用Spring AMQP连接对象。这个连接对象是由Spring注入的。但是,我不希望单元测试实际上与AMQP代理进行通信,因此我正在使用Mockito注入连接对象的模拟。 希望此代码示例中的注释清楚地提出问题。当Mockito将模拟依赖项注入到真实类中,并且在真实类上进行单元测试导致它调用该模拟对象时,您以后如何才能检索传递给注入的模拟对象的确切参

  • 我试图测试一个服务类,它在内部使用Spring AMQP连接对象。此连接对象由Spring注入。然而,我不希望我的单元测试实际与AMQP代理通信,所以我使用Mockito注入连接对象的mock。 希望这段代码示例中的注释清楚地阐述了这个问题。当Mockito将模拟依赖项注入到真实类中,并且对真实类的单元测试导致它调用模拟时,您以后如何检索传递给注入的模拟的确切参数?

  • 我想在方法中传递一个JFrame作为参数,可以吗? 这里是我想要的:

  • 我有一个lambda表达式,我希望能够传递和重用。代码如下: 这里的关键是,我希望能够将我在这里使用的lambda表达式传递到调用此代码的方法中,以便可以重用它。lambda表达式是我的。查询方法。我假设我想使用Action或Func,但我不太确定它的语法是什么,或者它是如何工作的。谁能给我举个例子吗?