Work in AndroidStudio. Want make mock of final class for AndroidInstrumentalTest with PowerMock. Added libs in gradle:
androidTestCompile ('org.powermock:powermock-api-mockito:1.5.6')
androidTestCompile ('org.powermock:powermock-core:1.5.6')
androidTestCompile ('org.powermock:powermock-module-junit4:1.5.6')
androidTestCompile 'org.mockito:mockito-core:1.10.8'
androidTestCompile 'com.google.dexmaker:dexmaker:1.1'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.1'
Make test class:
public class BluetoothTest extends ActivityInstrumentationTestCaseWithLogIn<PlanActivity> {
public BluetoothTest() {
super(PlanActivity.class);
}
@Override
public void setUp() throws Exception{
super.setUp();
BluetoothGatt gatt = PowerMockito.mock(BluetoothGatt.class);
}
}
Stack trace:
java.lang.VerifyError: org/mockito/cglib/core/ReflectUtils
at org.mockito.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:167)
at org.mockito.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:217)
at org.mockito.cglib.core.KeyFactory$Generator.create(KeyFactory.java:145)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:117)
........
at android.support.test.internal.runner.junit3.JUnit38ClassRunner.run(JUnit38ClassRunner.java:90)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
........
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:270)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1732)
I checked solutions from this issue, with no luck. Apparently solutions help with mockito-core, not powermock. It proved by another issue
I saw docs, then try added annotations @RunWith(PowerMockRunner.class) and @PrepareForTest(BluetoothGatt.class) on test class. Result :
java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation
at org.powermock.modules.junit4.common.internal.impl.JUnitVersion.getJUnitVersion(JUnitVersion.java:28)
at org.powermock.modules.junit4.common.internal.impl.JUnitVersion.isGreaterThanOrEqualTo(JUnitVersion.java:23)
at org.powermock.modules.junit4.PowerMockRunner.getRunnerDelegateImplClass(PowerMockRunner.java:38)
at org.powermock.modules.junit4.PowerMockRunner.<init>(PowerMockRunner.java:33)
........
at org.junit.runner.Computer.getSuite(Computer.java:26)
at android.support.test.internal.runner.TestRequestBuilder.classes(TestRequestBuilder.java:598)
at android.support.test.internal.runner.TestRequestBuilder.build(TestRequestBuilder.java:578)
at android.support.test.runner.AndroidJUnitRunner.buildRequest(AndroidJUnitRunner.java:542)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:269)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1732)
On non-rooted devices, APKs are subject to "verification", where the VM ensures that classes refer only to the implementations they are compiled against. Emulators and rooted devices aren't subject to this rule.
Unfortunately, implementations that hack classloaders (PowerMock and Robolectric) almost always violate that rule, because they create unexpected static class and method implementations (in order to mock them).
Keep the classloader hacking to your JVM unit tests, not your instrumentation tests, and instead extract any relevant interfaces into a wrapper you can control (and mock).