Sti*_*ing 6 java unit-testing java-8 java-stream
我最近开始使用 java 流并编写一个用户服务,它返回一个用户流。使用该用户流,我处理其他逻辑。
以下是我正在处理流的一段代码,它工作正常
try (Stream<User> users = userService.getStream()) {
users.forEach(user -> {
});
Run Code Online (Sandbox Code Playgroud)
但是当我开始编写 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)
Run Code Online (Sandbox Code Playgroud)
这是我的单元测试代码:
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");
Run Code Online (Sandbox Code Playgroud)
你能帮我用流编写测试用例/帮我解决这个问题吗?
当您使用 时thenReturn(users.stream()),您调用users.stream()一次并将该Stream对象移交给 Mockito 运行时,然后每次when(...)触发时都会返回相同的实例。
由于 aStream只能消耗一次,因此任何次要触发器都将失败。
你需要给 Mockito 一个工厂/供应商对象,它可以在Stream每次触发器触发时产生一个新的。Mockito 将其称为 an Answer,因此请thenAnswer(Answer<?> answer)改为调用。
when(userService.getStream()).thenAnswer(invo -> users.stream());
Run Code Online (Sandbox Code Playgroud)
您必须在 lambda 表达式中命名参数,但由于您不使用它,因此您可以随意调用它。我使用invo了invocation,为函数接口中的answer方法声明的参数的名称的缩写Answer。