Mock a method that returns a Stream and is called more than one time

眉间皱痕 提交于 2020-08-24 07:29:07

问题


MyStreamClass mock = mock(MyStreamClass.class);

when(mock.streamMethod()).thenReturn(Stream.of("A", "B"));

System.out.println(""+mock.streamMethod().findFirst());
System.out.println(""+mock.streamMethod().findFirst());

the second call of findFirst will throw java.lang.IllegalStateException: stream has already been operated upon or closed


回答1:


Try the thenAnswer instead of thenReturn:

Answer<Stream> answer = new Answer<Stream>() {
    public Stream answer(InvocationOnMock invocation) throws Throwable {
        return Stream.of("A", "B");
    }
};


when(mock.streamMethod()).thenAnswer(answer);

Now a new Stream will be created for each call to streamMethod.

Further read:

Here is an article I wrote on Dynamic Answering in Mockito that might be complementary.




回答2:


You're not mocking a Stream, you're creating one - and only one, which will be consumed after the first terminating method having been called on it, which is what you experience.

Most of the time, it's best to stick with mocking as far as possible, in your case

MyStreamClass mock = mock(MyStreamClass.class);
Stream mockStream = mock(Stream.class);
when(mock.streamMethod()).thenReturn(mockStream);

That should be enough for testing all clients of MyStreamClass - there's no point in getting actual results from the stream.

If that does not fit your design, you can alternatively use an Answer:

when(mock.streamMethod()).then(i -> Stream.of("A", "B"));

this will result in the stream being created every time the method is called.

Or, you can mock several calls with thenReturn().

when(mock.streamMethod()).thenReturn(Stream.of("A", "B"), Stream.of("A", "B"));

which will last you 2 calls.




回答3:


Try thenAnswer Using Java 8 Approach

when(mock.streamMethod()).thenAnswer(invocation -> Stream.of("A", "B"))



回答4:


Try this:

MyStreamClass mock = Mockito.mock(MyStreamClass.class);

Mockito.when(mock.streamMethod()).thenReturn(Stream.of("A", "B"));
Stream s = mock.streamMethod();

s.forEach(System.out::println);


来源:https://stackoverflow.com/questions/54634009/mock-a-method-that-returns-a-stream-and-is-called-more-than-one-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!