-
Notifications
You must be signed in to change notification settings - Fork 583
Description
Hi, I have a problem using mockito2 feature - mocking of final methods, with powrmock 1.7.0.RC4. When I include testCompile 'org.mockito:mockito-core:2.7.5'
into my build.gradle file and enable mock-maker-inline mechanism according to mockito documentation, everything works just fine.
At the moment I change the dependency to testCompile 'org.powermock:powermock-api-mockito2:1.7.0RC4'
the test fails with seemingly unrelated exceptions:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at com.test.app.map.MenuViewModelTest.run_action_on_close(MenuViewModelTest.kt:49)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:
- missing thenReturn()
- 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 if completedat com.test.app.map.MenuViewModelTest.run_action_on_close(MenuViewModelTest.kt:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
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.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
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.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
or
org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
Runnable$$EnhancerByMockitoWithCGLIB$$b48288eb cannot be returned by doAction()
doAction() should return int
***
If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
- This exception might occur in wrongly written multi-threaded tests.
Please refer to Mockito FAQ on limitations of concurrency testing.- A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies -
- with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.
The test is in kotlin but it's the same in java, I have tried.
@Test
fun run_action_on_close() {
val runnable = mock<Runnable>(Runnable::class.java) //mock Runnable.class
doReturn(runnable).`when`(mMenuItem)!!.getAction(mContext)
mViewModel!!.onItemClick(mMenuItem)
verify<Runnable>(runnable).run()
}
The real problem is definitely in final method getAction(Context context)
. When this method is not final everything works again. But as I mentioned this exact test works with mockito-core:2.7.5
dependency. With powermock-api-mockito2:1.7.0RC4
(which depends on exact same mockito-core:2.7.5
version) the test fails.
I'm running this on Windows 10 x64.