我有以下设置:
public interface CommandRunner
{
void run(String cmd, InputStream is) throws IOException;
}
public class CommandRunnerInputFile
{
private final CommandRunner commandRunner;
public CommandRunnerInputFile(CommandRunner commandRunner) {
this.commandRunner = commandRunner;
}
public void run(String command, File inputFile) throws IOException {
try (FileInputStream is = new FileInputStream(inputFile)) {
this.commandRunner.run(command, is);
}
}
}
@ExtendWith(MockitoExtension.class)
public class TestCommandRunnerInputFile
{
@Mock CommandRunner commandRunner;
@Captor ArgumentCaptor<InputStream> inputStream;
private CommandRunnerInputFile commandRunnerInputFile;
@BeforeEach
void initService() {
commandRunnerInputFile = new CommandRunnerInputFile(commandRunner);
}
@Test
public void testHappyPath() throws IOException {
ClassLoader classLoader = this.getClass().getClassLoader();
File file = new File(classLoader.getResource("MyTestInputFile.txt").getFile());
commandRunnerInputFile .run("MyApplication.exe", file);
verify(commandRunner).run(eq("MyApplication.exe"), inputStream.capture());
assertEquals('c', (char)inputStream.getValue().read());
}
}
当我运行这个测试时,它失败了,并出现以下异常:
java.io.IOException: Stream Closed
at java.io.FileInputStream.read0(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:207)
这对我来说是有意义的,因为在执行方法的过程中,底层的FileInputStream
在完成执行时是关闭的。也就是说,在FileInputStream
被Mockito捕获的时间点,它是打开的。但等我确认通过了(并尝试验证其内容)它是关闭的。我能做什么不是简单地捕获InputStream
对象本身,而是实际捕获其内容以进行验证?
1条答案
按热度按时间fykwrbwg1#
ArgumentCaptor在这里没有帮助,因为Stream很可能已经被关闭了,例如从try-with-resources。所以你必须在测试期间用mock捕获内容:
当你的方法返回一个void时,mocking看起来有点不同:
我使用Guava来获取InputStream内容,但您也可以使用ApacheIOUtils或其他许多选项之一described here。