Android
真机使用Mockito-1.10.19
+Dexmaker-1.2
在Mock
仅包内可见类时报告如下错误:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
java.lang.UnsupportedOperationException: cannot proxy inaccessible class class com.yunos.tv.shake.biz.PackageAccessible at com.android.dx.stock.ProxyBuilder.buildProxyClass(ProxyBuilder.java:269) at com.android.dx.mockito.DexmakerMockMaker.createMock(DexmakerMockMaker.java:56) 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) at com.yunos.tv.shake.biz.PackageAccessibleTest.setUp(PackageAccessibleTest.java:17) at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191) at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176) at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555) at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1853) Caused by: java.lang.IllegalAccessError: Class com.yunos.tv.shake.biz.PackageAccessible extended by class PackageAccessible_Proxy is inaccessible (declaration of 'PackageAccessible_Proxy' appears in /data/data/com.yunos.tv.shake.biz.test/cache/Generated_179875952.jar) at dalvik.system.DexFile.defineClassNative(Native Method) at dalvik.system.DexFile.defineClass(DexFile.java:226) at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:219) at dalvik.system.DexPathList.findClass(DexPathList.java:321) at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:54) at java.lang.ClassLoader.loadClass(ClassLoader.java:511) at java.lang.ClassLoader.loadClass(ClassLoader.java:469) at com.android.dx.stock.ProxyBuilder.loadClass(ProxyBuilder.java:284) at com.android.dx.stock.ProxyBuilder.buildProxyClass(ProxyBuilder.java:266) ... 15 more |
被测试类代码如下:
1 2 3 4 |
package com.yunos.tv.shake.biz; class PackageAccessible { } |
注意上述被测试类前面没有声明public
,因此默认是default
访问,也就是包内可见。我们下面的测试代码跟被测试类属于同一个包名package com.yunos.tv.shake.biz
,因此,按理说,是可以正常访问的。
测试类的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.yunos.tv.shake.biz; import android.test.AndroidTestCase; import org.mockito.Mockito; public class PackageAccessibleTest extends AndroidTestCase { protected void setUp() throws Exception { super.setUp(); /*解决BUG dexcache == null (and no default could be found; consider setting the 'dexmaker.dexcache' system pr*/ System.setProperty( "dexmaker.dexcache", getContext().getCacheDir().getPath()); PackageAccessible packageAccessible = Mockito.mock(PackageAccessible.class); } } |
这个问题只在ART
虚拟机下面发生异常,相同的代码在Dalvik
下面是完全正常的。
问题发生的原因暂时还不能确定,应该是ART
虚拟机实现功能的时候的不兼容导致的。
解决方法为在测试代码中声明一个继承被测试类的子类,并且把子类声明成public
。
如下:
1 2 3 4 |
package com.yunos.tv.shake.biz; public class PackageAccessibleShadow extends PackageAccessible { } |
修改后的测试代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.yunos.tv.shake.biz; import android.test.AndroidTestCase; import org.mockito.Mockito; public class PackageAccessibleTest extends AndroidTestCase { protected void setUp() throws Exception { super.setUp(); /*解决BUG dexcache == null (and no default could be found; consider setting the 'dexmaker.dexcache' system pr*/ System.setProperty( "dexmaker.dexcache", getContext().getCacheDir().getPath()); PackageAccessibleShadow packageAccessible = Mockito.mock(PackageAccessibleShadow.class); } } |
即可解决上述问题。