在调试时,我在使用Mockito 1.10时遇到了一些非常奇怪的事情。我希望有人能解释这里的行为:
当我运行以下程序时,我的线程挂起,我的测试永远不会返回。创建的Java进程的CPU也是天文数字!
@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)方法。在您的情况下,它返回null,因为它没有mock定义,这会导致copy方法中出现无休止的循环。
您可以更改默认的mock行为,也可以手动添加read(buff)方法的定义。
您需要设置mock来调用InputStream
的实际方法,而此时您还没有将它们清除为
final InputStream mis = Mockito.mock(InputStream.class, Mockito.CALLS_REAL_METHODS);
javadoc声明
当使用遗留代码时,此实现可能会有所帮助。什么时候如果使用此实现,未构建的方法将委托给真正的实施。这是一种创建部分mock对象的方法默认情况下调用真实方法
默认情况下,Mockito会嘲笑一切。您首先使用的ByteStreams#copy
方法调用InputStream#read(byte[])
。由于mockito已经对其进行了嘲讽,它将返回0,ByteStreams#copy
将其解释为"从该流中有更多内容要读取",并继续读取(无限循环)。
通过使用Mockito.CALLS_REAL_METHODS
,您告诉Mockito调用InputStream
中的实际实现,它将委托给read()
,您已将其截断以引发异常。