powermock
powermock copied to clipboard
Mockito mock-maker-inline does not work with Robolectric
PowerMock is supposed to solve the integration problem with Mockito mock-maker-inline. However, since it uses its custom PowerMockMaker, it cannot initialize Byte Buddy mock maker.
The problem is this one: "This mock maker is not supported on Android" when running side by side with Robolectric. It seems like Robolectric already solved this issue here: https://github.com/robolectric/robolectric/pull/2761
Caused by: org.mockito.exceptions.base.MockitoInitializationException:
Could not initialize inline Byte Buddy mock maker. (This mock maker is not supported on Android.)
Libraries used: mockitoVersion -> 2.8.9 powermockVersion -> 1.7.0 robolectricVersion -> 3.4-rc2
When you try to mock a simple final class with the JUnit4 or PowerMock runners you can see this error:
java.lang.RuntimeException: Invoking the beforeTestMethod method on PowerMock test listener org.powermock.api.extension.listener.AnnotationEnabler@4229bb3f failed.
at org.powermock.tests.utils.impl.PowerMockTestNotifierImpl.notifyBeforeTestMethod(PowerMockTestNotifierImpl.java:84)
at org.powermock.modules.junit4.internal.impl.NotificationBuilder$OngoingTestRun.<init>(NotificationBuilder.java:90)
at org.powermock.modules.junit4.internal.impl.NotificationBuilder.testStartHasBeenFired(NotificationBuilder.java:233)
at org.powermock.modules.junit4.internal.impl.PowerMockRunNotifier.fireTestStarted(PowerMockRunNotifier.java:112)
at org.junit.internal.runners.model.EachTestNotifier.fireTestStarted(EachTestNotifier.java:42)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:323)
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.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner$2.call(DelegatingPowerMockRunner.java:149)
at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner$2.call(DelegatingPowerMockRunner.java:141)
at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner.withContextClassLoader(DelegatingPowerMockRunner.java:132)
at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner.run(DelegatingPowerMockRunner.java:141)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:121)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:57)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
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.AppMainV2.main(AppMainV2.java:131)
Caused by: java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker
at org.mockito.internal.configuration.plugins.PluginLoader$1.invoke(PluginLoader.java:66)
at com.sun.proxy.$Proxy14.createMock(Unknown Source)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMethodInvocationControl(DefaultMockCreator.java:116)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMock(DefaultMockCreator.java:69)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.mock(DefaultMockCreator.java:46)
at org.powermock.api.mockito.PowerMockito.mock(PowerMockito.java:192)
at org.powermock.api.extension.listener.AnnotationEnabler.standardInject(AnnotationEnabler.java:107)
at org.powermock.api.extension.listener.AnnotationEnabler.beforeTestMethod(AnnotationEnabler.java:55)
at org.powermock.tests.utils.impl.PowerMockTestNotifierImpl.notifyBeforeTestMethod(PowerMockTestNotifierImpl.java:82)
... 30 more
Caused by: java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in sun.misc.CompoundEnumeration@73ee04c8
at org.mockito.internal.configuration.plugins.PluginLoader.loadImpl(PluginLoader.java:101)
at org.mockito.internal.configuration.plugins.PluginLoader.loadPlugin(PluginLoader.java:45)
at org.mockito.internal.configuration.plugins.PluginRegistry.<init>(PluginRegistry.java:18)
at org.mockito.internal.configuration.plugins.Plugins.<clinit>(Plugins.java:17)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.getMockMaker(DefaultMockCreator.java:140)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMethodInvocationControl(DefaultMockCreator.java:99)
... 36 more
Caused by: java.lang.IllegalStateException: Failed to load MockMaker implementation: org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker
at org.powermock.api.mockito.mockmaker.MockMakerLoader.load(MockMakerLoader.java:39)
at org.powermock.api.mockito.mockmaker.PowerMockMaker.<init>(PowerMockMaker.java:45)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at org.mockito.internal.configuration.plugins.PluginLoader.loadImpl(PluginLoader.java:96)
... 41 more
Caused by: org.mockito.exceptions.base.MockitoInitializationException:
Could not initialize inline Byte Buddy mock maker. (This mock maker is not supported on Android.)
Java : 1.8
JVM vendor name : JetBrains s.r.o
JVM vendor version : 25.112-b736
JVM name : OpenJDK 64-Bit Server VM
JVM version : 1.8.0_112-release-b736
JVM info : mixed mode
OS name : Mac OS X
OS version : 10.12.5
at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.<init>(InlineByteBuddyMockMaker.java:172)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at org.powermock.api.mockito.mockmaker.MockMakerLoader.load(MockMakerLoader.java:36)
... 48 more
Caused by: java.lang.IllegalStateException: Error during attachment using: net.bytebuddy.agent.ByteBuddyAgent$AttachmentProvider$Compound@55607a32
at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:379)
at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:353)
at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:321)
at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:307)
at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.<clinit>(InlineByteBuddyMockMaker.java:102)
... 54 more
Caused by: java.lang.reflect.InvocationTargetException
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 net.bytebuddy.agent.Attacher.install(Attacher.java:78)
at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:374)
... 58 more
Caused by: java.lang.NullPointerException
at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:182)
... 64 more
@xian and @raphw could you help me to clarify the issue and current state with https://github.com/robolectric/robolectric/pull/2761
PowerMock uses the following code to load InlineByteBuddyMockMaker
.
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader == null) {
loader = ClassLoader.getSystemClassLoader();
}
String mockMakerClassName = mockitoConfiguration.getMockMakerClass();
try {
Class<?> mockMakerClass = loader.loadClass(mockMakerClassName);
Object mockMaker = mockMakerClass.newInstance();
return MockMaker.class.cast(mockMaker);
} catch (Exception e) {
throw new IllegalStateException("Failed to load MockMaker implementation: " + mockMakerClassName, e);
}
I guess that in this case Robolectric ClassLoader is used and everything should be fine.
I'm not sure, but maybe correct way to load a class will be
Class.forName(mockMakerClassName).newInstance()
The inline Mock maker needs to load a class explicitly as it must inject a type into the bootstrap class loader. I guess some explicit class loading is triggering some code before the inline mock maker is loaded such that this yields a race?
I am however confused over this mistake:
Caused by: java.lang.NullPointerException at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:182)
Could you look at the line in question and debug what is missing? Are you running on a JDK?
@raphw,
As I see in stacktrace it was OpenJDK
Java : 1.8 JVM vendor name : JetBrains s.r.o JVM vendor version : 25.112-b736 JVM name : OpenJDK 64-Bit Server VM JVM version : 1.8.0_112-release-b73
@raphw @thekingnothing Yes, it's OpenJDK because I'm using Robolectric
did you ever solve this issue?