Mockito在简单测试中抛出OutOfMemoryError

时间:2013-07-02 23:56:39

标签: java heap mockito

我尝试使用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();
    }
}

3 个答案:

答案 0 :(得分:14)

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

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

  

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

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());

答案 1 :(得分:12)

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

https://code.google.com/p/mockito/issues/detail?id=84

详细介绍了此问题

答案 2 :(得分:1)

这并没有给我带来Out Of Memory错误,因此我只能假设您需要在运行时增加可用的堆空间量。 Here's how you can do that.