Mockito:通缉但未被援引

时间:2016-02-19 17:32:57

标签: java unit-testing mockito

我有以下测试方法:

MyClass myClass= Mockito.mock(MyClass.class);
Mockito.when(myClass.methodUsedInMethodBeingTested(Matchers.any(MyTypeParam.class))).thenReturn(Collections.<X, Y> emptyMap());

assertNull(myClass.methodToTest(myObject));
Mockito.verify(myClass).methodUsedInMethodBeingTested(Matchers.any(MyTypeParam.class));

methodUsedInMethodBeingTested是我想要模拟并返回空地图的方法。但是我收到的失败信息是

  

通缉但未调用myClass.methodUsedInMethodBeingTested()

MyClass
{
   public XYZ methodToTest()
   {
    ....
    ....
    Map<X,Y> mp = methodUsedInMethodBeingTested(myTypeParam);
    .....
   }

   public Map<X,Y> methodUsedInMethodBeingTested(MyTypeParam myTypeParam)
   {
    .....
   }
}

2 个答案:

答案 0 :(得分:10)

你误解了模拟是什么。当你在做什么

MyClass myClass = Mockito.mock(MyClass.class);
// ...
assertNull(myClass.methodToTest(myObject));

您实际上并未在真实对象上调用methodToTest。你在模拟上调用了methodToTest,默认情况下,什么也不做,只返回null,除非它被存根。引自Mockito docs

  

默认情况下,对于返回值的所有方法,mock返回null,空集合或适当的原始/原始包装值(例如:0,false,...表示int / Integer,boolean / Boolean,...) 。

这解释了您的后续错误:该方法实际上未在模拟上调用。

看来你想要的是spy而不是:

  

您可以创建真实对象的间谍。当你使用间谍时,会调用真正的方法(除非方法被存根)。

虽然注意到警告:因为它是被调用的真实方法,所以不应该使用Mockito.when而是更喜欢Mockito.doReturn(...).when,否则该方法将被调用一次为真。如果你考虑表达式:

Mockito.when(myClass.methodUsedInMethodBeingTested(Matchers.any(MyTypeParam.class))).thenReturn(Collections.<X, Y> emptyMap());
             ^-----------------------------------^
                 this will be invoked by Java

必须评估方法when的参数,但这意味着将调用方法methodUsedInMethodBeingTested。由于我们有一个间谍,这是将被调用的真正方法。所以,请使用:

MyClass spy = Mockito.spy(new MyClass());
Mockito.doReturn(Collections.<X, Y> emptyMap()).when(spy).methodUsedInMethodBeingTested(Matchers.any(MyTypeParam.class));
assertNull(spy.methodToTest(myObject));
Mockito.verify(spy).methodUsedInMethodBeingTested(Matchers.any(MyTypeParam.class));

答案 1 :(得分:2)

您正在调用模拟实例上的methodToTest。因为你没有配置它,只返回null,它不会尝试调用任何实际方法的实现。