我正在嘲笑一个相当复杂的对象层次结构,当我正在研究它时,可能涉及到大量的方法。如果我错过了并且保留了非虚拟方法,默认情况下Mockito会返回null,这会很快触发NPE并且我很容易找到它。但是,如果我错过了一个void方法,那么默认行为就是什么也不做,这经常会导致下游的失败并且更难调试。我想更改此默认值,例如抛出一个自定义异常,但似乎找不到方法。 提前致谢!
答案 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方法与外部足够模拟服务的存根相关,那么它可能是您的服务正在做的代码味道,或者您的系统 - 测试的相互作用定义不够好。如果您经常发现自己处于这种情况,可能需要进行记录,重构或两者兼而有之。