【问题标题】:mock methods in same class同一类中的模拟方法
【发布时间】:2017-01-05 01:08:53
【问题描述】:

我正在使用 Mockito 来模拟我正在为其编写测试的同一类中的方法。我在 SO (Mocking method in the same class) 上看到了其他答案,但我可能误解了它们,因为我遇到了问题。

 class Temp() {

    public boolean methodA(String param) {

         try {

             if(methodB(param))
                   return true;

             return false;
         } catch (Exception e) {
               e.printStackTrace();
         }
    }
 }

我的测试方法:

 @Test
 public void testMethodA() {

    Temp temp = new Temp();
    Temp spyTemp = Mockito.spy(temp);

    Mockito.doReturn(true).when(spyTemp).methodB(Mockito.any()); 
    boolean status = temp.methodA("XYZ");

    Assert.assertEquals(true, status);
 }

然而,由于方法 B 的定义被执行,我得到了打印出来的期望。 我的理解是使用 spyTemp 会嘲笑 methodB 的定义。然而,情况似乎并非如此。

谁能解释我哪里出错了?

【问题讨论】:

    标签: java unit-testing mocking mockito


    【解决方案1】:

    第一个问题是你必须使用 spyTest 对象来期待 Mockito 的某些东西。这里和测试不一样。 spyTemp 被 Mockito 对象 temp 包裹。

    另一个问题是你只存根methodB(),但你试图运行methodA()。是的,在您实现methodA() 时,您调用methodB(),但您调用this.methodB(),而不是spyTemp.methodB()。 在这里你必须明白,只有当你在temp 的实例上调用它时,模拟才会起作用。它由一个 Mockito 代理包裹,该代理捕获您的调用,如果您重写了某些方法,它将调用您的新实现而不是原始实现。但是由于调用了原始方法,因此在其中您对 Mockito 代理一无所知。因此,只有在运行 spyTemp.methodB()

    时才会调用您的“覆盖”方法

    这应该可行:

    Mockito.doReturn(true).when(spyTemp).methodB(Mockito.any()); 
    boolean status = spyTemp.methodA("XYZ");
    

    【讨论】:

    • 你的意思是spyTemp.methodA("XYZ")而不是spyTemp.methodB("XYZ")?
    • 是的,应该是spyTemp.methodA("XYZ")
    • "这里你必须明白,只有当你在 temp 实例上调用它时,模拟才会起作用。"您的意思是调用实例 spyTemp,而不是 temp?
    【解决方案2】:

    你创建了一个间谍并嘲笑了methodB()。那是正确的!但是您在原始对象上调用了methodA()。要获得正确的结果,请在 spy 上调用它

    boolean status = spyTemp.methodA("XYZ");
    

    【讨论】:

      【解决方案3】:

      请注意 Mockito 文档中的以下内容:

      Mockito 不将调用委托给传递的真实实例,而是 它实际上创建了它的副本。所以如果你保留真实的实例并且 与它互动,不要指望间谍知道那些 交互及其对真实实例状态的影响。推论是 当一个 unstubbed 方法被调用在 spy 上但 不在 真实实例,您不会看到对真实实例的任何影响。

      这是专门针对您的情况。您保留对temp 的引用,然后调用它的methodA。 Mockito 根本没有监视那个实例。它在监视spyTemp。所以调用了普通的methodB。

      请注意,您应该完全避免对新代码进行部分模拟。

      【讨论】:

        猜你喜欢
        • 2014-04-08
        • 2011-08-13
        • 2016-07-17
        • 1970-01-01
        • 2015-06-13
        • 2018-01-09
        • 2021-09-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多