在编写单元测试用例的时候,如果被测试类是与AIDL相关的类,不管是直接调用,还是被测试类继承了AIDL生成的类,由于AIDL类是在编译期间动态生成的,并且每次构建都会重新生成一次(类名相同,但是Hash可能会变,文件修改日期必然变更)。
然而,由于PowerMock调用Objenesis库为了加快编译速度,会缓存同名的类,这样导致在运行时进行类型转换的时候无法通过校验,报告如下错误:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | org.mockito.exceptions.base.MockitoException:      ClassCastException occurred while creating the mockito proxy :       class to mock : 'com.squareup.otto.Bus', loaded by classloader : 'org.robolectric.internal.bytecode.InstrumentingClassLoader@1593948d'       created class : 'com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196', loaded by classloader : 'org.robolectric.internal.bytecode.InstrumentingClassLoader@1593948d'       proxy instance class : 'com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196', loaded by classloader : 'org.mockito.internal.creation.util.SearchingClassLoader@618ff5c2'       instance creation by : ObjenesisInstantiator     You might experience classloading issues, disabling the Objenesis cache *might* help (see MockitoConfiguration)         at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:61)         at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:49)         at org.powermock.api.mockito.repackaged.CglibMockMaker.createMock(CglibMockMaker.java:24)         at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:45)         at com.acme.android.myapp.services.gcm.handlers.RequestLogoutHandlerTest.setup(RequestLogoutHandlerTest.java:39)         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)         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.RunBefores.evaluate(RunBefores.java:24)         at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251)         at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)         at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)         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.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152)         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:78)         at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)         at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)         at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)     Caused by: java.lang.ClassCastException: Cannot cast com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196 to com.squareup.otto.Bus         at java.lang.Class.cast(Class.java:3369)         at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:59)         at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:49)         at org.powermock.api.mockito.repackaged.CglibMockMaker.createMock(CglibMockMaker.java:24)         at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:45)         at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33)         at org.mockito.internal.MockitoCore.mock(MockitoCore.java:59)         at org.mockito.Mockito.mock(Mockito.java:1285)         at org.mockito.Mockito.mock(Mockito.java:1163)         ... 36 more     org.mockito.exceptions.base.MockitoException:      ClassCastException occurred while creating the mockito proxy :       class to mock : 'com.squareup.otto.Bus', loaded by classloader : 'org.robolectric.internal.bytecode.InstrumentingClassLoader@1593948d'       created class : 'com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196', loaded by classloader : 'org.robolectric.internal.bytecode.InstrumentingClassLoader@1593948d'       proxy instance class : 'com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196', loaded by classloader : 'org.mockito.internal.creation.util.SearchingClassLoader@618ff5c2'       instance creation by : ObjenesisInstantiator     You might experience classloading issues, disabling the Objenesis cache *might* help (see MockitoConfiguration)         at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:61)         at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:49)         at org.powermock.api.mockito.repackaged.CglibMockMaker.createMock(CglibMockMaker.java:24)         at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:45)         at com.acme.android.myapp.services.gcm.handlers.RequestLogoutHandlerTest.setup(RequestLogoutHandlerTest.java:39)         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)         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.RunBefores.evaluate(RunBefores.java:24)         at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251)         at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)         at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)         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.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152)         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:78)         at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)         at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:6 | 
解决方法就是阻止Objenesis的缓存功能。在测试用例的根目录下新建文件,如下:
| 1 2 3 4 5 6 7 8 9 | package org.mockito.configuration; public class MockitoConfiguration extends DefaultMockitoConfiguration {     @Override     public boolean enableClassCache() {         return false;     } } | 
参考链接
- How can I test class extends auto-generated Stub class from AIDL file
- How to test remote android aidl service
- Mockito ClassCastException after using PowerMock
- ClassCastException exception when running Robolectric test with Power Mock on multiple files
- Mockito ClassCastException after using PowerMock

 打开对应模块的build.gradle文件
打开对应模块的build.gradle文件