Mockito Invocation Listener确定来源

时间:2017-11-12 19:58:13

标签: java unit-testing testing mocking mockito

我有一个简单的接口并使用InvocationListener进行模拟(通过详细日志记录选项模拟)。

    final SampleInterface sampleIf = mock(SampleInterface.class, withSettings().verboseLogging());

    System.out.println("-> Modify return value");
    when(sampleIf.getIt()).thenReturn("Result");
    System.out.println("-> Call getter");
    assertEquals("Result", sampleIf.getIt());
    System.out.println("-> Verify getter call");
    verify(sampleIf).getIt();

因此我得到以下输出:

  

- >修改返回值

     ######在mock / spy上记录方法调用#1 ######## sampleInterface.getIt();调用: - >在      

de.sambalmueslie.samanunga.test.TesterTest.test(TesterTest.java:31)
  已返回:“null”

     

- >呼叫getter

     ######在mock / spy上记录方法调用#2 ######## stubbed: - >在      

de.sambalmueslie.samanunga.test.TesterTest.test(TesterTest.java:31)   sampleInterface.getIt();调用: - >在   de.sambalmueslie.samanunga.test.TesterTest.test(TesterTest.java:33)
  已返回:“结果”(java.lang.String)

     

- >验证getter call

     ######在mock / spy上记录方法调用#3 ######## sampleInterface.getIt();调用: - >在      

de.sambalmueslie.samanunga.test.TesterTest.test(TesterTest.java:35)
  已返回:“null”

我的问题是,我怎么能从mockito框架的调用中隔离出真正的getter调用?

我喜欢以下输出:

  

- >修改返回值    - >呼叫getter

     ######在mock / spy上记录方法调用#2 ######## stubbed: - >在      

de.sambalmueslie.samanunga.test.TesterTest.test(TesterTest.java:31)   sampleInterface.getIt();调用: - >在   de.sambalmueslie.samanunga.test.TesterTest.test(TesterTest.java:33)
  已返回:“结果”(java.lang.String)

     

- >验证getter call

编辑 - 没有模拟的示例

    System.out.println("-> Calling anything not mocked");
    sampleIf.callMe();
    System.out.println("-> Verify call");
    verify(sampleIf).callMe();
  

- >召唤任何不被嘲笑的东西

     ######在mock / spy上记录方法调用#4 ######## sampleInterface.callMe();调用: - >在      

de.sambalmueslie.samanunga.test.TesterTest.test(TesterTest.java:38)
  已返回:“null”

     

- >验证电话

     ######在mock / spy上记录方法调用#5 ######## sampleInterface.callMe();调用: - >在      

de.sambalmueslie.samanunga.test.TesterTest.test(TesterTest.java:40)
  已返回:“null”

1 个答案:

答案 0 :(得分:1)

从您的问题陈述中,我相信您希望从被测代码中收到存根上的调用通知,并在制定对测试代码的期望时排除从测试代码生成的调用。嘲笑对象。

您确实可以使用InvocationListener来实现此目的。我在下面写了一个监听器,它过滤传递给你的例子中使用的详细调用记录器的通知。

final InvocationListener listener = new InvocationListener() {
  final VerboseMockInvocationLogger logger = new VerboseMockInvocationLogger();         

  @Override
  public void reportInvocation(MethodInvocationReport methodInvocationReport) {
    if (methodInvocationReport.getLocationOfStubbing() != null) {
      logger.reportInvocation(methodInvocationReport);                  
    }
  }
};

MockSettings settings = Mockito.withSettings().invocationListeners(listener); 
SampleInterface sampleIf = Mockito.mock(SampleInterface.class, settings);
...

产生输出:

-> Modify return value
-> Call getter
############ Logging method invocation #1 on mock/spy ########
   stubbed: -> at a.a.A.a(A.java:29)
sampleInterface.getIt();
   invoked: -> at a.a.A.a(A.java:31)
   has returned: "Result" (java.lang.String)

-> Verify getter call

我用Mockito 1.10.19来测试它。

修改

好的,我明白了 - 您还希望收到 unstubbed 方法调用的通知。在这种情况下,我认为单独使用InvocationListener是不够的。因此,我不知道一个简单的方法来歧视"真实"方法通过Mockito提供的框架从期望定义中调用(存根或未存在)。

如果事先知道哪些方法是存根的,哪些方法不存在,则可以使用默认的Answer来进行未存在的方法调用。创建模拟时可以提供默认答案(Mockito.mock(type, defaultAnswer)。只会调用未存在的方法调用。除了InvocationListener之外,还可以使用它来收集模拟的方法调用。 。

然而,即使我们可以将我们知道的方法调用与那些不存在的方法调用分开,我怀疑我们是否愿意将逻辑分成两个不同的结构,我不建议因为它似乎不一致且容易出错。