java - 如何在每次调用 doReturn 时返回一个新实例?

标签 java mocking mockito

我有以下测试用例:

ClassPathResource resource = new ClassPathResource(...);
doReturn(resource.getInputStream()).when(someMock).getInputStream();

我在其中读取了一些资源并在测试中将其返回。在实际生产代码中以异步、计划的方式调用此方法存在一些不确定性 - 因此我无法完全控制它被调用的次数准确,尽管返回的数据始终相同(或者应该是)。

换句话说,如果调用该方法并且读取流的次数比预期多,这可能可能导致随机失败的测试,因为流尚未(且无法)重置,并且已经在EOF

我明确希望在测试上下文中同步调用它,并且正在使用Awaitility.await()来测试这些类型的场景,所以不幸的是这对我来说不是一个选择。

现在,可能解决此问题的“愚蠢”方法如下:

doReturn(resource.getInputStream()).doReturn(resource.getInputStream()).<...>.when(someMock).getInputStream();

但这仍然不能解决实际问题,充其量只是一个创可贴。

我实际上期望像下面这样的东西能够工作:

ClassPathResource resource = new ClassPathResource(...);
doReturn(resource.call().getInputStream()).when(someMock).getInputStream();

但不幸的是,这也只检索底层 Stream 一次。

如何在每次 doReturn() 调用时提供一个新的实例? mockito 能做到这一点吗?对于我想做的事情有其他方法吗?

最佳答案

我不太确定我是否同意您的要求。

你首先要做的是ClassPathResource resource = new ClassPathResource(...);,我假设这是一次性的事情。然后每次调用都会返回resource.getInputStream()。根据定义,你不能有多个实例 - 你要求做一件事并试图做另一件事。那么你想要什么?您可以使用一些问题重组。另外,您首先在单元测试中使用 ClassPathResource 做什么?

与此同时,我能猜到你想要什么的最好方法就是我能得到的对你的问题最字面的解释,并完全忽略任何和所有伪代码(因为它完全与你的问题相矛盾)。也就是说,您需要为每次方法调用提供一个完全独立的 InputStream 实例。这部分很简单。

Mockito.doAnswer(new Answer<InputStream>() {
            @Override
            public InputStream answer(InvocationOnMock invocation)
                    throws Throwable {
                return Mockito.mock(InputStream.class);
            }
        }).when(resource.getInputStream());

关于java - 如何在每次调用 doReturn 时返回一个新实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60975456/

相关文章:

java - 如何编写 Junit 测试用例来测试字符串中的重复元素计数

Java NIO 从输入流读取大文件

java - 从 JsonObject 中的 Json 中删除键

java - toBinaryString 类型错误

reactjs - Jest 模拟类型错误 : Cannot read property 'credential' of undefined on library react-native-firebase

java - 使用 spring boot 的 @MockBean 时创建严格的模拟?

java - 无法加载驱动程序类 org.mariadb.jdbc.Driver

模拟 TCP 套接字以进行单元测试的 Python 方法

scala - 如何在 Scala 的测试中分解对象功能

java - Mockito 空指针异常