I'm trying to avoid using PowerMockito here. We have legacy code which contains methods that are both static and void and there are tests which need to mock them. Is there a way to do it or is refactoring legacy code the only way here?
class MySample {
public static void sampleMethod(String argument){
//do something
}
}
If I use the general MockStatic syntax, it asks me to return something:
MockedStatic <MySample> sampleMock = Mockito.mockStatic( MySample.class );
sampleMock.when(() -> MySample.sampleMethod(Mockito.any(String.class)));
Exception:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at com.mytests.Test.setMock(Test.java:35)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, which is not supported
3. you are stubbing the behaviour of another mock inside before 'thenReturn' instruction is completed
Edit: Please note that I'm looking to mock a method that is BOTH static and void.
What do you want to happen when the mocked method gets called?
The default behavior is that nothing happens. By calling sampleMock.when()
, you indicated that you wanted to change from the default behavior to something else. Mockito is complaining because you didn't then follow that up with a call to then___()
to specify what should happen instead.
There are a few different things I can think of that you might want to have happen:
As previously stated, this is the default behavior, so if this is all you want, you can just remove the second line and it should work. But, if you really need to have a when
call (e.g. for argument capture), you can instead finish off the line with an empty thenAnswer
:
sampleMock.when(() -> MySample.sampleMethod(Mockito.any(String.class)))
.thenAnswer(invocation -> null);
sampleMock.when(() -> MySample.sampleMethod(Mockito.any(String.class)))
.thenCallRealMethod();
sampleMock.when(() -> MySample.sampleMethod(Mockito.any(String.class)))
.thenAnswer(invocation -> {
// insert code to do something else here
return null;
});
sampleMock.when(() -> MySample.sampleMethod(Mockito.any(String.class)))
.thenThrow(RuntimeException.class);
As previously mentioned, the default behavior is to do nothing, but I learned it's also possible to specify an alternate default behavior by providing an Answer
when creating the mock. For example, to have the default behavior call the real method instead:
MockedStatic <MySample> sampleMock = Mockito.mockStatic( MySample.class, Mockito.CALLS_REAL_METHODS );
But beware - as noted by Marc in this answer, the real method will still be called even if you override the default behavior! This may be fixed in the future; see Marc's answer for some good references