2

I am mocking a fairly complex object hierarchy, and as I am working through it, there's a large number of methods that can be involved. If I miss and leave unstubbed a non-void method, Mockito by default makes it return null which quickly triggers a NPE and it's easy for me to locate it. However, if I miss a void method, the default behavior is to do nothing, which frequently leads to failures further downstream and much harder to debug. I'd like to change this default, e.g. throw a custom exception, but don't seem to find a way. Thanks in advance!

Forelight
  • 305
  • 5
  • 13

1 Answers1

5

You can write a default answer, passed in as a parameter to Mockito.mock. Unfortunately, due to limitations of Java annotations, it's not so easy to make this default behavior for @Mock-annotated fields.

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());

Though you would be forced to use doAnswer() syntax for void methods anyway, be aware if you change the above to include non-void methods that you will be forced to use doReturn() syntax. This is because when(foo.bar()).thenReturn(baz) relies on the call to foo.bar() within the when() statement, but you will have stubbed it to throw an exception.

Also, if you find it hard to tell which void methods are relevant to stub on an external-enough-to-mock service, it may be a code smell that your service is doing to much, or that your system-under-test's interactions are not defined well enough. If you find yourself in this situation often, it may be time to document, refactor, or both.

Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251