如何在Mockito中覆盖未加载的void方法的默认行为?

时间:2016-03-10 19:18:54

标签: java junit mockito

我正在嘲笑一个相当复杂的对象层次结构,当我正在研究它时,可能涉及到大量的方法。如果我错过了并且保留了非虚拟方法,默认情况下Mockito会返回null,这会很快触发NPE并且我很容易找到它。但是,如果我错过了一个void方法,那么默认行为就是什么也不做,这经常会导致下游的失败并且更难调试。我想更改此默认值,例如抛出一个自定义异常,但似乎找不到方法。 提前致谢!

1 个答案:

答案 0 :(得分:2)

您可以编写默认答案,作为参数传递给Mockito.mock。遗憾的是,由于Java注释的限制,为@Mock - 带注释的字段制作此默认行为并不容易。

public static class ThrowingAnswer implements Answer<Object> {
  @Override public Void answer(InvocationOnMock invocation) throws Throwable {
    if (invocation.getMethod().getReturnType() == Void.TYPE) {
      throw new UnsupportedOperationException(String.format(
          "Method %s not stubbed on %s",
          invocation.getMethod().getName(),
          invocation.getMock()));
    }
    return Answers.RETURNS_DEFAULTS.answer(invocation);
  }
}

YourClass mockYourClass = Mockito.mock(YourClass.class, new ThrowingAnswer());

尽管您将被迫使用doAnswer()方法的void语法,但请注意如果您更改上述内容以包含非空方法您将被强制使用使用doReturn()语法。这是因为when(foo.bar()).thenReturn(baz)依赖于foo.bar()语句中对when()的调用,但是你会将其存根以引发异常。

此外,如果您发现很难分辨哪些void方法与外部足够模拟服务的存根相关,那么它可能是您的服务正在做的代码味道,或者您的系统 - 测试的相互作用定义不够好。如果您经常发现自己处于这种情况,可能需要进行记录,重构或两者兼而有之。