Mockito在一个简单的测试中抛出一个OutOfMemoryError

我尝试使用Mockito来模拟数据库池(仅用于检索数据),但是当运行在一段时间内检索到许多模拟连接的性能测试时,它会耗尽内存。

这是一个简化的自包含代码,它在我的机器上进行大约150,000次循环迭代后抛出OutOfMemoryError(尽管似乎没有任何东西可以全局保存,并且所有东西都应该是垃圾可收集的)。 我究竟做错了什么?

import static org.mockito.Mockito.when; import java.sql.Connection; import org.mockito.Mock; import org.mockito.MockitoAnnotations; public class Test1 { static class DbPool { public Connection getConnection() {return null;} } @Mock private DbPool dbPool; @Mock private Connection connection; public Test1() { MockitoAnnotations.initMocks(this); when(dbPool.getConnection()).thenReturn(connection); for(int i=0;i<1000000;i++) { dbPool.getConnection(); System.out.println(i); } } public static void main(String s[]) { new Test1(); } } 

问题是模拟对象正在记住每次调用的细节,以防您希望稍后进行validation。 最终,它将不可避免地耗尽内存。 您需要做的是偶尔使用Mockito.reset静态方法重置模拟,并再次存根您的方法。 不幸的是,如果不重置存根,就无法清除模拟的validation信息。

https://code.google.com/p/mockito/issues/detail?id=84详细介绍了此问题

david-wallace的响应解释了为什么遇到OOM:模拟对象正在记住每次调用的细节。

但同样重要的问题是:现在该怎么办呢? 除了大卫已经建议的,最新的Mockito版本1.10.19以及即将推出的2.0.x现在支持所谓的stubOnly (参见javadoc ):

stubOnly:仅存根模拟不记录方法调用,从而节省了内存但不允许validation调用。

Scala用法示例:

 import org.mockito.Mockito val list = Mockito.mock(classOf[Foo], Mockito.withSettings().stubOnly()) // The syntax is a bit more concise when using ScalaTest's MockitoSugar val foo = mock[Foo](Mockito.withSettings().stubOnly()) 

Java使用示例(未经测试):

 import org.mockito.Mockito; Foo mock = Mockito.mock(Foo.class, Mockito.withSettings().stubOnly()); 

这并没有为我抛出OutOfMemory错误,所以我只能假设你需要增加运行它时可用的堆空间量。 这是你如何做到这一点。