Mockito InvocationImpl在TestSuite测试中保留

时间:2016-07-25 17:09:11

标签: java memory-leaks mockito

我有一个JUnit测试套件,有大约800个测试。其中大部分都与Spring有关,而且大量使用Mockito进行模拟/间谍行为。我开始遇到内存不足错误。在分析hprof转储时,我注意到>在测试之间保留的Mockito InvocationImpls消耗了30%的堆。

在测试课程完成后,有没有办法清除这些?我不想使用Mockito.reset(mock),因为模拟初始化因每次测试而异。如果没有,似乎我需要拆分测试以适应泄漏。

this link开始,Mockito团队认识到这些是在执行方法后作为验证的权衡。但是我想知道是否有人找到了清除这些内容的方法,因此大量的单元测试可以在套件中串联起来。

1 个答案:

答案 0 :(得分:2)

我找到了部分工作。在我的例子中,绝大多数InvocationImpl实例是在一个使用spy()创建Real Partial Mock的测试用例中创建的,因此可以覆盖一个方法。我正在使用Mockito 1.10.19,所以我将部分模拟构造从spy()切换到mock( <class>, withSettings().spiedInstance( realInstance ).defaultAnswer( CALLS_READ_MATHODS ).stubOnly() )

虽然这可以防止在此模拟上使用verify(),但stubOnly()会阻止模拟在测试期间为每个对间谍进行的调用存储InvocationImpl的实例,并显着减少堆使用

由于我的Mocks通常在Spring上下文文件中使用Springockito创建,因此我需要对bean定义进行丑陋的返工以匹配mock()调用,如下所示。但这允许间谍在Spring-wired域类中使用。

  <bean id="realInstance" class="<Real Instance Class>" />
  <bean id="instSpySettings" class="org.mockito.Mockito" factory-method="withSettings" />
  <bean id="instSpyPartialMock" factory-bean="instSpySettings" factory-method="spiedInstance">
    <constructor-arg>
      <ref local="realInstance" />
    </constructor-arg>
  </bean>
  <bean id="instSpyDefaultAnswers" factory-bean="instSpyPartialMock" factory-method="defaultAnswer">
    <constructor-arg><util:constant static-field="org.mockito.Mockito.CALLS_REAL_METHODS"/></constructor-arg>
  </bean>
  <bean id="instSpyStubOnly" factory-bean="instSpyDefaultAnswers" factory-method="stubOnly" />
  <bean id="spyInstance" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="<Real Instance Class>" />
    <constructor-arg>
      <ref local="instSpyStubOnly" />
    </constructor-arg>
  </bean>