如何让 JUnit 接受任何 Lambda 表达式
How to make JUnit take any Lambda expression
我正在使用 SpringAMQP 测试生产者方法(基本上是 AMQP 模板),就像这样。
public void send(Message message, Throwable error, String queue, String routingKey) {
this.amqpTemplate.convertAndSend(
RabbitConfiguration.ERROR_EXCHANGE,
RabbitConfiguration.ERROR_ROUTING_KEY,
message,
messageMetaData -> {
messageMetaData.getMessageProperties().getHeaders().put("x-death-reason", error.getMessage());
return messageMetaData;
}
);
}
我正在使用以下内容测试此代码
import static org.hamcrest.Matchers.any;
....
@Test
public void will_create_error_message_if_incorrect_payload_is_given() {
AmqpTemplate amqpTemplate = mock(AmqpTemplate.class);
Throwable throwable = mock(Throwable.class);
when(throwable.getMessage()).thenReturn("first");
when(throwable.getStackTrace()).thenReturn(null);
ErrorMessageProducer errorMessageProducer = new ErrorMessageProducer(amqpTemplate);
Message message = MessageBuilder.withBody("test".getBytes()).build();
verify(amqpTemplate).convertAndSend(
eq(RabbitConfiguration.ERROR_EXCHANGE),
eq(RabbitConfiguration.ERROR_ROUTING_KEY),
any(Message.class),
Mockito.any()
);
}
但我得到 Invalid use of argument matchers! 4 matchers expected, 3 recorded
。有什么方法可以使用 Lambda 进行测试或完全忽略 Lambda。
问题是因为你用错了any()
。
verify(amqpTemplate).convertAndSend(
eq(RabbitConfiguration.ERROR_EXCHANGE),
eq(RabbitConfiguration.ERROR_ROUTING_KEY),
any(Message.class),
Mockito.any()
);
此处您的第三个参数使用 org.hamcrest.Matchers.any
中的 any
,但是第四个参数使用正确的 Mockito.any()
。所以第三个参数没有被检测为匹配器,而是像普通参数一样受到威胁。
要检查您的 lambda,您应该使用 ArgumentCaptor.
ArgumentCaptor<Runnable> argument = ArgumentCaptor.forClass(Runnable.class);
verify(mock).doSomething(any(), argument.capture());
argument.getValue().run();
...verify that lambda called your services...
您可以将 Runnable
更改为您的 lambda 实际表示的任何类型的函数:即 Function
/Callable
。
我正在使用 SpringAMQP 测试生产者方法(基本上是 AMQP 模板),就像这样。
public void send(Message message, Throwable error, String queue, String routingKey) {
this.amqpTemplate.convertAndSend(
RabbitConfiguration.ERROR_EXCHANGE,
RabbitConfiguration.ERROR_ROUTING_KEY,
message,
messageMetaData -> {
messageMetaData.getMessageProperties().getHeaders().put("x-death-reason", error.getMessage());
return messageMetaData;
}
);
}
我正在使用以下内容测试此代码
import static org.hamcrest.Matchers.any;
....
@Test
public void will_create_error_message_if_incorrect_payload_is_given() {
AmqpTemplate amqpTemplate = mock(AmqpTemplate.class);
Throwable throwable = mock(Throwable.class);
when(throwable.getMessage()).thenReturn("first");
when(throwable.getStackTrace()).thenReturn(null);
ErrorMessageProducer errorMessageProducer = new ErrorMessageProducer(amqpTemplate);
Message message = MessageBuilder.withBody("test".getBytes()).build();
verify(amqpTemplate).convertAndSend(
eq(RabbitConfiguration.ERROR_EXCHANGE),
eq(RabbitConfiguration.ERROR_ROUTING_KEY),
any(Message.class),
Mockito.any()
);
}
但我得到 Invalid use of argument matchers! 4 matchers expected, 3 recorded
。有什么方法可以使用 Lambda 进行测试或完全忽略 Lambda。
问题是因为你用错了any()
。
verify(amqpTemplate).convertAndSend(
eq(RabbitConfiguration.ERROR_EXCHANGE),
eq(RabbitConfiguration.ERROR_ROUTING_KEY),
any(Message.class),
Mockito.any()
);
此处您的第三个参数使用 org.hamcrest.Matchers.any
中的 any
,但是第四个参数使用正确的 Mockito.any()
。所以第三个参数没有被检测为匹配器,而是像普通参数一样受到威胁。
要检查您的 lambda,您应该使用 ArgumentCaptor.
ArgumentCaptor<Runnable> argument = ArgumentCaptor.forClass(Runnable.class);
verify(mock).doSomething(any(), argument.capture());
argument.getValue().run();
...verify that lambda called your services...
您可以将 Runnable
更改为您的 lambda 实际表示的任何类型的函数:即 Function
/Callable
。