【问题标题】:Mockito: Wanted but not invokedMockito:想要但没有被调用
【发布时间】:2016-02-19 17:32:56
【问题描述】:

我有如下测试方法:

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)
   {
    .....
   }
}

【问题讨论】:

    标签: java unit-testing mockito


    【解决方案1】:

    您误解了什么是模拟。当你在做的时候

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

    您实际上并没有在您的真实对象上调用methodToTest。您在模拟上调用methodToTest,默认情况下,它什么都不做并返回null,除非它被存根。引用Mockito docs:

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

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


    看来你想要的是spy

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

    警告说明:由于调用的是真正的方法,因此您不应使用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. 我不能这样做 MyClass spy = Mockito.spy(MyClass.class);正如它所说,Type mIsmatch 无法从 Class 转换为 MyClass。 2. 你能不能更好地解释一下“虽然是一个警告:因为它是被调用的真正方法,所以你不应该使用 Mockito.when 而是更喜欢 Mockito.doReturn(...).when,否则该方法将真正调用一次:"
    • @Vwin 我已经编辑过了。我使用了一种新方法,你的 Mockito 版本中不能出现这种方法。关于你的第二个顾虑,我也澄清了。
    • 那是完美的。有效。谢谢@RomanVottner。谢谢 Tunaki,你太棒了 :) 并且解释更有意义。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多