繁体   English   中英

如何为 Java Stream 编写 Junit

[英]How to write Junit for Java Stream

我最近开始使用 java 流并编写一个用户服务,它返回一个用户流。 使用该用户流,我处理其他逻辑。

以下是我正在处理流的一段代码,它工作正常

try (Stream<User> users = userService.getStream()) {
    users.forEach(user -> {
    });

但是当我开始编写 Junit 时,它失败并显示以下错误消息。

java.lang.IllegalStateException: stream has already been operated upon or closed
    at java.util.stream.AbstractPipeline.sourceStageSpliterator(AbstractPipeline.java:279)
    at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:647) 
    at com.test.UserService.sendBulkNotification(UserService.java:47)
    at com.test.UserServiceTest.sendNotificationTest(UserServiceTest.java:64) 

这是我的单元测试代码:

List<User> users = new ArrayList<>();
for(long i = 1; i <= 5; i++) {
    User user = new User();
    user.setId(i);
    users.add(user);
}

when(userService.getStream()).thenReturn(users.stream());
userService.sendNotification("user", 1, "test.com");

你能帮我用流编写测试用例/帮我解决这个问题吗?

当您使用thenReturn(users.stream()) ,您调用users.stream()一次并将该Stream对象移交给 Mockito 运行时,然后每次触发when(...)都会返回相同的实例.

由于Stream只能使用一次,因此任何辅助触发器都将失败。

你需要给 Mockito 一个工厂/供应商对象,它可以在每次触发器触发时产生一个新的Stream Mockito 将其称为Answer ,因此请thenAnswer(Answer<?> answer)调用thenAnswer(Answer<?> answer)

when(userService.getStream()).thenAnswer(invo -> users.stream());

您必须在 lambda 表达式中命名参数,但由于您不使用它,因此您可以随意调用它。 我使用invo作为invocation缩写,它是为Answer功能接口中的answer方法声明的参数的名称。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM