【问题标题】:How to mock/test method that returns void, possibly in Mockito如何模拟/测试返回 void 的方法,可能在 Mockito 中
【发布时间】:2011-06-17 08:00:53
【问题描述】:

我遇到了一个问题,但找不到优雅的解决方案。

所以问题在于 Selenium Web 驱动程序的模拟,我不知道应该如何测试/模拟 void 方法。

public void clickAndWait(String locator) {
    if(isElementPresent(locator) == false) throw some exception;
    selenium.clickAndWait(); //a problematic delegating call to selenium
}

所以我要问的是,如何正确测试这样的方法,一个测试将是抛出异常,但是如何正确地测试我委托给的那个 void 方法?

【问题讨论】:

标签: java testing mocking mockito


【解决方案1】:

来自 Mockito documentation 的以下代码示例说明了如何模拟 void 方法:

doThrow(new RuntimeException()).when(mockedList).clear();

// following throws RuntimeException:
mockedList.clear();

【讨论】:

  • Mockito 文档链接现在不可用:(
  • 好吧,如果我不需要需要抛出异常呢?
  • @Godfather 那你想嘲笑什么?该方法是无效的,所以你没有返回任何东西。如果您只是确保调用了该方法,则可以使用 verify(..)。
【解决方案2】:
doAnswer(new Answer<Void>() {
        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {

            return null;
        }
    }).when(mock).method((SomeClass) anyObject());

【讨论】:

  • +1 有用的答案显示了当方法采用参数时如何使用 doThrow/doAnswer/etc,即使用anyObject() 进行强制转换。
  • 嗨,Marcin,我尝试给出相同的结果并得到了 stackoverflow.com/questions/27142314/… 中提到的错误,您能看一下吗?
【解决方案3】:

之前的答案一直强调在每次通话时都做某事(可能抛出异常)。这样,当您执行以下操作时:

doThrow(new RuntimeException()).when(mockedList).clear();

然后像这样调用存根服务(或逻辑):

mockedList.clear();

它会产生一个异常。如果您想测试方法是否正常运行,可能会编写积极的测试用例。可以通过以下方式模拟 void 返回方法:

doNothing().when(mockedList).clear();

这意味着由于您为 mockedList 模拟存根了 clear() 方法,您可以确定此方法不会影响单元的逻辑,并且您仍然可以检查流程的其余部分而不生成例外。

【讨论】:

【解决方案4】:

你也可以使用:

  • 方法 Mockito.verify(mock/spy) 检查该方法被调用了多少次。
  • 或使用argument captor 来查看/检查传递给 void 方法的一些参数。

【讨论】:

    【解决方案5】:

    你可以在你的方法调用中抛出一个异常,这里是一个小例子:

    doThrow(new RuntimeException()).when(mockedList).clear();
    

    然后你调用mockedList.clear(); mocked 方法会抛出异常。

    或者你可以计算你的方法被调用了多少次,这里有一个小例子:

    verify(mockedList, times(1)).clear(); 
    

    【讨论】:

      【解决方案6】:

      在 Java 8 中,这可以变得更简洁

      doAnswer((i) -> {
        // Do stuff with i.getArguments() here
        return null;
      }).when(*mock*).*method*(*methodArguments*);
      

      return null; 很重要,如果没有它,编译将失败并出现一些相当模糊的错误,因为它无法为doAnswer 找到合适的覆盖。

      【讨论】:

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