为什么 Mockito 对 InputStreams 的行为很奇怪?
Why is Mockito behaving weird with InputStreams?
在调试时,我在使用 Mockito 1.10 时遇到了一些非常奇怪的事情。我希望有人能解释这里的行为:
当我 运行 以下内容时,我的线程挂起并且我的测试从不 returns。 CPU 创建的 Java 进程也达到了天文数字!
@Test(expected = IOException.class)
public void mockitoWeirdness() throws IOException {
final InputStream mis = mock(InputStream.class);
doThrow(IOException.class).when(mis).read();
ByteStreams.copy(mis, new ByteArrayOutputStream());
}
当我如下手动存根这个方法时,抛出了预期的 IOException:
@Test(expected = IOException.class)
public void nonMockitoExpected() throws IOException {
final InputStream mis = new InputStream() {
@Override
public int read() throws IOException {
throw new IOException();
}
};
ByteStreams.copy(mis, new ByteArrayOutputStream());
}
如果能帮助理解 mockito 方法失败的方式和原因,那就太棒了。
如果您查看 ByteStreams 实现,您会发现使用了 read(buf) 方法。
在您的情况下,它 returns null 因为没有针对它的模拟定义,这会导致 copy 方法中出现无限循环。
您可以更改 default mock behaviour 或手动添加 read(buff) 方法的定义。
你需要设置你的 mock 来调用 InputStream
的真正方法,当你还没有存根时
final InputStream mis = Mockito.mock(InputStream.class, Mockito.CALLS_REAL_METHODS);
javadoc 州
This implementation can be helpful when working with legacy code. When
this implementation is used, unstubbed methods will delegate to the
real implementation. This is a way to create a partial mock object
that calls real methods by default.
默认情况下,Mockito 模拟所有内容。您首先使用的 ByteStreams#copy
方法调用 InputStream#read(byte[])
。由于 mockito 已经嘲笑了它,它将 return 0 ByteStreams#copy
解释为 "there is more to read from this stream" 并继续阅读(无限循环)。
通过使用 Mockito.CALLS_REAL_METHODS
,您告诉 Mockito 调用 InputStream
中的实际实现,它将委托给 read()
,您已将其存根以抛出异常。
在调试时,我在使用 Mockito 1.10 时遇到了一些非常奇怪的事情。我希望有人能解释这里的行为:
当我 运行 以下内容时,我的线程挂起并且我的测试从不 returns。 CPU 创建的 Java 进程也达到了天文数字!
@Test(expected = IOException.class)
public void mockitoWeirdness() throws IOException {
final InputStream mis = mock(InputStream.class);
doThrow(IOException.class).when(mis).read();
ByteStreams.copy(mis, new ByteArrayOutputStream());
}
当我如下手动存根这个方法时,抛出了预期的 IOException:
@Test(expected = IOException.class)
public void nonMockitoExpected() throws IOException {
final InputStream mis = new InputStream() {
@Override
public int read() throws IOException {
throw new IOException();
}
};
ByteStreams.copy(mis, new ByteArrayOutputStream());
}
如果能帮助理解 mockito 方法失败的方式和原因,那就太棒了。
如果您查看 ByteStreams 实现,您会发现使用了 read(buf) 方法。 在您的情况下,它 returns null 因为没有针对它的模拟定义,这会导致 copy 方法中出现无限循环。
您可以更改 default mock behaviour 或手动添加 read(buff) 方法的定义。
你需要设置你的 mock 来调用 InputStream
的真正方法,当你还没有存根时
final InputStream mis = Mockito.mock(InputStream.class, Mockito.CALLS_REAL_METHODS);
javadoc 州
This implementation can be helpful when working with legacy code. When this implementation is used, unstubbed methods will delegate to the real implementation. This is a way to create a partial mock object that calls real methods by default.
默认情况下,Mockito 模拟所有内容。您首先使用的 ByteStreams#copy
方法调用 InputStream#read(byte[])
。由于 mockito 已经嘲笑了它,它将 return 0 ByteStreams#copy
解释为 "there is more to read from this stream" 并继续阅读(无限循环)。
通过使用 Mockito.CALLS_REAL_METHODS
,您告诉 Mockito 调用 InputStream
中的实际实现,它将委托给 read()
,您已将其存根以抛出异常。