我需要用lambda Consumer测试一个使用另一个接口作为依赖注入的类。
@Builder
public class Interactor {
private final Gateway gateway;
void process(String message, Consumer<String> response){
gateway.process(message, uuid -> {
response.accept(uuid.toString());
});
}
}依赖关系的定义如下:
public interface Gateway {
void process(String message, Consumer<UUID> uuid);
}我如何模拟网关,以便为我的测试提供UUID值响应?
这就是我到目前为止所尝试的:
@Test
void whillReturnTheInjectedUUIDValueTest() {
UUID uuid = UUID.randomUUID();
Gateway gateway = Mockito.mock(Gateway.class);
Mockito.when(gateway.process("ignored", uuid1 -> {return uuid;}));
Interactor.builder().gateway(gateway).build().process("ignored", s -> {
Assertions.assertEquals(uuid.toString(), s);
});
}我应该如何向消费者提供返回值?
发布于 2018-05-13 03:37:12
这一次成功了
@Test
void willReturnTheInjectedUUIDValueTest() {
UUID uuid = UUID.randomUUID();
Gateway gateway = Mockito.mock(Gateway.class);
doAnswer(ans -> {
Consumer<UUID> callback = (Consumer<UUID>) ans.getArgument(1);
callback.accept(uuid);
return null;
}).when(gateway).process(Mockito.any(String.class), Mockito.any(Consumer.class));
Interactor.builder().gateway(gateway).build().process("ignored", s -> {
Assertions.assertEquals(uuid.toString(), s);
});
}这个答案是-> https://stackoverflow.com/a/47226374/148397的提示
发布于 2018-05-06 20:59:41
现在,我最终在没有Mockito的情况下嘲笑了我自己的内部类。
class InteractorTest {
@Test
void whillReturnTheInjectedUUIDValueTest() {
UUID uuid = UUID.randomUUID();
Gateway gateway = GatewayMock.builder().value(uuid).build();
Interactor.builder().gateway(gateway).build().process("ignored", s -> {
Assertions.assertEquals(uuid.toString(), s);
});
}
@Builder
private static class GatewayMock implements Gateway {
private final UUID value;
@Override
public void process(String message, Consumer<UUID> uuid) {
uuid.accept(value);
}
}
}发布于 2018-05-07 06:59:13
你想要什么..。
是为了验证Interactor#process逻辑的结果,它接受一个Consumer<String>,基本上只是使用一个回调Consumer<String>参数的Consumer<UUID>实现调用Gateway#process。
理想情况下,您只需调用Interactor#process并验证对您提供的Consumer<String>的调用即可。
你的问题是。
由Gateway的实现者触发Consumer<UUID> (以及随后的Consumer<String>)。所以你需要注入一个Gateway的实现来做这件事。
解决方案是...
按照您提供的答案(即使用伪对象而不是Mock),除非在您的生产代码中有一个可以轻松使用的Gateway的真实实现(但我假设您已经在这样做了)。
你能用Mockito做到吗?当然,您可以在模拟对象的方法参数上调用方法,如下面的答案所示:https://stackoverflow.com/a/16819818/775138 -但是如果您可以在一行中提供足够的Gateway实现,为什么还要这样做:
Gateway gw = (message, consumer) -> consumer.accept(uuid);其中uuid是您之前构造的UUID实例。因此,不需要为此声明一个静态内部类。
然而..。
您的断言有一个重要的问题:如果Interactor什么也不做,而不是调用Gateway,那么您提供的Consumer<String> (包含断言)将不会被触发,因此您的测试将通过!只需将该值赋给测试类的成员变量,并在lambda外部进行断言。
https://stackoverflow.com/questions/50199260
复制相似问题