Mockito:通缉但未被调用

2022-09-03 01:18:07

我有以下测试方法:

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

Wanted 但未调用 myClass.methodUsedInMethodBeingTested()

.

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

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

答案 1

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

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

您实际上并没有调用您的真实对象。您正在调用模拟,默认情况下,它不执行任何操作并返回,除非它被存根。引用Mockito文档methodToTestmethodToTestnull

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

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


看来你在这里想要的是一个间谍

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

但需要注意的是:由于调用的是真正的方法,因此您不应使用,而应首选 ,否则该方法将被调用一次。如果您考虑以下表达式:Mockito.whenMockito.doReturn(...).when

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

必须计算该方法的参数,但这意味着将调用该方法。由于我们有间谍,因此将调用它才是真正的方法。因此,相反,请使用:whenmethodUsedInMethodBeingTested

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

答案 2

您正在调用模拟实例上的 。由于您尚未以其他方式对其进行配置,因此仅返回 null,因此它不会尝试调用任何实际方法的实现。methodToTest


推荐