I'm using Mockito. I want to throw a RuntimeException
when an unstubbed method is called.
Is there any way to do this?
I'm using Mockito. I want to throw a RuntimeException
when an unstubbed method is called.
Is there any way to do this?
You can set a default answer for a mock. All methods that aren't stubbed will use this default answer.
public void testUnstubbedException() {
// Create a mock with all methods throwing a RuntimeException by default
SomeClass someClass = mock( SomeClass .class, new RuntimeExceptionAnswer() );
doReturn(1).when(someClass).getId(); // Must use doReturn
int id = someClass.getId(); // Will return 1
someClass.unstubbedMethod(); // Will throw RuntimeException
}
public static class RuntimeExceptionAnswer implements Answer<Object> {
public Object answer( InvocationOnMock invocation ) throws Throwable {
throw new RuntimeException ( invocation.getMethod().getName() + " is not stubbed" );
}
}
Note that you cannot use when
with this functionality, since the method is called before when
(How does mockito when() invocation work?) and it will throw a RuntimeException
before the mock goes into stubbing mode.
Therefore, you must use doReturn
for this to work.
The best way to do this is with the verifyNoMoreInteractions
and ignoreStubs
static methods. Call these after the "act" part of your test; and you'll get a failure if any unstubbed methods were called but not verified.
verifyNoMoreInteractions(ignoreStubs(myMock));
This is described at https://static.javadoc.io/org.mockito/mockito-core/2.8.47/org/mockito/Mockito.html#ignore_stubs_verification although I believe that the code example there currently contains a misprint.
Refinement over Tom's answer https://stackoverflow.com/a/15835255/1484823
Mockito now provides builtin support with a default answer which throws exception, and can be specified either with @Mock annotation
@Mock(answer = Answers.RETURNS_SMART_NULLS)
private BackingAppDeploymentService backingAppDeploymentService;
or
private BackingAppDeploymentService backingAppDeploymentService =
Mockito.mock(BackingAppDeploymentService.class, new ReturnsSmartNulls());
See https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#RETURNS_SMART_NULLS
If your code uses the object returned by an unstubbed call you get a NullPointerException. This implementation of Answer returns SmartNull instead of null. SmartNull gives nicer exception message than NPE because it points out the line where unstubbed method was called. You just click on the stack trace.
ReturnsSmartNulls first tries to return ordinary values (zeros, empty collections, empty string, etc.) then it tries to return SmartNull. If the return type is final then plain null is returned.
ReturnsSmartNulls will be probably the default return values strategy in Mockito 4.0.0
You mock an entire class and the result is that all methods will return null.
Then you can use doReturn(...)
to change that behavior. Similarly, you can use doThrow(...)
to make (as I recall only void
) methods throw exceptions.
Does that answer your question?