In other words:
How to use "doAnswer" stubbing for static mocks in mockito?
I didn't find a way to do it. I found only the "when(...).then(...)" way to stub static methods.
For Example:
I want to linearize method SwingUtilities.invokeLater (Why? I want it simple :-)).
Using the latest Mockito I can mock static methods and write somthing like this (in try-with-resource block of course):
Answer<Object> directInvocationAnswer = invocation -> {
((Runnable) invocation.getArgument(0)).run();
return null;
};
MockedStatic<SwingUtilities> mockedStatic = Mockito.mockStatic(SwingUtilities.class, CALLS_REAL_METHODS);
mockedStatic.when(() -> SwingUtilities.invokeLater(any(Runnable.class))).then(directInvocationAnswer);
It works, but I can see a NPE in the event queue. It doesn't work. At all.
It is understandable, because () -> SwingUtilities.invokeLater(any(Runnable.class)) invokes real SwingUtilities.invokeLater with null as parameter (any() returns null) and mockito can't stop the real invocation, because it does not known (at this point in time) - is is a "normal" invocation in production code or a stubbing invocation.
And I can't remove CALLS_REAL_METHODS, because I want to use other methods of the class.
Yes, I can trick mockito and avoid calling of SwingUtilities.invokeLater(null):
Answer<Object> directInvocationAnswer = invocation -> {
((Runnable) invocation.getArgument(0)).run();
return null;
};
MockedStatic<SwingUtilities> mockedStatic = Mockito.mockStatic(SwingUtilities.class, CALLS_REAL_METHODS);
any(Runnable.class); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
mockedStatic.when(() ->
SwingUtilities.invokeLater(MyUtils::nop)) // <<<<<<<<<<<<<<<<<<<<<<
.then(directInvocationAnswer);
return mockedStatic;
It works here, but it's very ugly und it does not work in all cases - the real method was invoked at least once.
Are there any ways to use doAnswer-like stubbing for static mocks in mockito?