We are trying to define a UnitTest where we mock an object which I here called x
for simplicity:
...
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import org.kubek2k.springockito.annotations.SpringockitoContextLoader;
import org.kubek2k.springockito.annotations.WrapWithSpy;
...
@ContextConfiguration(
loader = SpringockitoContextLoader.class,
inheritLocations = true)
public class SyncServiceIntegrationTest extends AbstractIntegrationTest {
@Autowired
@WrapWithSpy
private EventDrivenIssueDeliveryConfirmer x;
...
@Before
public void setUp() {
...
doNothing().when(x).foobar(any(Event.class));
}
...
i.e. we want our UT (not shown here) to later NOT call the method foobar
on that object x
.
Strange enough we get an NPE during initialization of this UT-class. The NPE is thrown by method foobar()
, when the passed argument is null.
As turned out this call with argument null
happens in the line doNothing()...
in the setup
-method which in our understanding is supposed to just define the mock-object's stubbing. But instead it evaluates the any(Event.class)
-expression which apparently yields null
and with that result it then calls the foobar(...)
-method on x
which causes the NPE.
Besides the NullPointerException we also get an error message from Mockito:
java.lang.NullPointerException: null
... <stack trace omitted for brevity>
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced or misused argument matcher detected here:
-> at ch.sst.integration.SyncServiceIntegrationTest .setUp(SyncServiceIntegrationTest.java:69)
You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
... <examples omitted for brevity>
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at ch.sst.integration.SyncServiceIntegrationTest .setUp(SyncServiceIntegrationTest.java:69)
...
Why is that so??? Why is our stubbing considered "unfinished"? What are we missing here?
Later addition:
The issue seems to have to do with the fact that class
EventDrivenIssueDeliveryConfirmer
is marked with @Transactional. Removing/commenting that lets the UT succeed. But of course that's no workaround - we need that annotation.
At least this provides a hint in which direction to search. The wrapping caused by @Transactional and the wrapping done by Mockito seem to step on each other's foot here.