mock-maker-inline makes test fail with "NotAMockException Argument passed to Mockito.mockingDetails() should be a mock" on non-final non-static class
I have a JUnit test where I have 5 mocks and one of mocked classes is final, I enabled mock-maker-inline to overcome that problem and now test passes but at the end of test execution I also get NotAMockException at:
org.mockito.exceptions.misusing.NotAMockException: Argument passed to Mockito.mockingDetails() should be a mock, but is an instance of class ...Locals! at org.mockito.internal.runners.DefaultInternalRunner$1$2.testFinished(DefaultInternalRunner.java:63) at org.junit.runner.notification.SynchronizedRunListener.testFinished(SynchronizedRunListener.java:56) at org.junit.runner.notification.RunNotifier$7.notifyListener(RunNotifier.java:190) at org.junit.runner.notification.RunNotifier$SafeNotifier.run(RunNotifier.java:72) at org.junit.runner.notification.RunNotifier.fireTestFinished(RunNotifier.java:187) at org.junit.internal.runners.model.EachTestNotifier.fireTestFinished(EachTestNotifier.java:38) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:331) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:74) at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:80) at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39) at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) ...
The mocking is very simple:
@Mock private Locals locals; //class @Mock private Globals globals; // class @Mock private Cache cache; // interface @Mock private Reminds reminds; // final class @Mock private Employeereminds employeereminds; // class
… followed by couple of when().thenReturn() setups to make it work together
During the test mocks looks like this:
locals = {Locals@3233} globals = {Globals@3234} cache = {Cache$MockitoMock$665734991@3237} "cache" reminds = {Reminds@3235} employeereminds = {Employeereminds@3236}
I am using Mockito 2.25.0 also tried 2.28.2 but no difference.
I can refactor my test to also test the content of final class but I prefer my test isolated. I could also use powermock but have seen similar problems reported with powermock.
Did anybody stumble upon such issue and found a decent workaround?
EDIT: I did some more investigation, I removed Locals
Mock and got same error on Globals
mock. Then I removed Globals
mock and got (!?) following exception (@ v2.28.2):
org.mockito.exceptions.misusing.NotAMockException: Argument passed to Mockito.mockingDetails() should be a mock, but is an instance of class Cache$MockitoMock$149288076! at org.mockito.internal.runners.DefaultInternalRunner$1$2.testFinished(DefaultInternalRunner.java:63) at org.junit.runner.notification.SynchronizedRunListener.testFinished(SynchronizedRunListener.java:56) at org.junit.runner.notification.RunNotifier$7.notifyListener(RunNotifier.java:190) at org.junit.runner.notification.RunNotifier$SafeNotifier.run(RunNotifier.java:72) at org.junit.runner.notification.RunNotifier.fireTestFinished(RunNotifier.java:187) at org.junit.internal.runners.model.EachTestNotifier.fireTestFinished(EachTestNotifier.java:38) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:331) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:74) at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:80) at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39) at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) ...
Ok, I’ve found the issue: I was invoking
Mockito.framework().clearInlineMocks();
in a code invoked by @After
annotation, but the correct way is to do it in code invoked by @AfterClass
annotation, otherwise Mockito own verification is run after you cleared the mocks.