我想使用Robolectric对其内容视图包含自定义非Android Activity
的{{1}}的行为进行单元测试。所以我想嘲笑这个观点。
我尝试使用Mockito,但自定义视图由View
系统服务使用LayoutInflater
实例化;而且,代码的特定部分在最终方法中。所以Mockito在这个问题上无法帮助我。
PowerMock在我看来是一个可行的解决方案,因为它的类加载器“魔法”可能会拦截我想要模拟的自定义视图的构造;但是,基本的单元测试甚至不测试任何东西,也不创建测试活动,如
Class.newInstance
(其中@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })
@PrepareForTest({View.class, CustomView.class})
@SuppressWarnings("unused")
public class PowerMockAndRobolectricUnitTest {
@Rule
public PowerMockRule rule = new PowerMockRule();
@Test
public void testInstantiation() throws ClassNotFoundException {
CustomView mockCustomView = PowerMockito.mock(CustomView.class);
}
}
是Android Studio生成的自定义视图,没有任何其他更改)导致CustomView
语句中出现运行时错误,并显示此堆栈跟踪:
PowerMockito.mock
有问题的课程似乎是java.lang.IllegalStateException: Failed to transform class with name android.view.View. Reason: by javassist.bytecode.BadBytecode: getVerticalFadingEdgeLength ()I in android.view.View: failed to resolve types
at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:267)
at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:180)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:70)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.lang.ClassLoader.defineClass(ClassLoader.java:643)
at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:270)
at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:180)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:70)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at mycompany.myapp.test.customview.PowerMockAndRobolectricUnitTest.testInstantiation(PowerMockAndRobolectricUnitTest.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
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.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.powermock.modules.junit4.rule.PowerMockStatement$1.run(PowerMockRule.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:1873)
at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:773)
at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:638)
at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:401)
at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:98)
at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:78)
at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:57)
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.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:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: javassist.CannotCompileException: by javassist.bytecode.BadBytecode: getVerticalFadingEdgeLength ()I in android.view.View: failed to resolve types
at javassist.CtBehavior.insertBefore(CtBehavior.java:777)
at javassist.CtBehavior.insertBefore(CtBehavior.java:734)
at org.powermock.core.transformers.impl.MainMockTransformer.modifyMethod(MainMockTransformer.java:197)
at org.powermock.core.transformers.impl.MainMockTransformer.allowMockingOfStaticAndFinalAndNativeMethods(MainMockTransformer.java:133)
at org.powermock.core.transformers.impl.MainMockTransformer.transform(MainMockTransformer.java:65)
at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:252)
... 50 more
Caused by: javassist.bytecode.BadBytecode: getVerticalFadingEdgeLength ()I in android.view.View: failed to resolve types
at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:111)
at javassist.bytecode.MethodInfo.rebuildStackMap(MethodInfo.java:440)
at javassist.bytecode.MethodInfo.rebuildStackMapIf6(MethodInfo.java:422)
at javassist.CtBehavior.insertBefore(CtBehavior.java:768)
... 55 more
Caused by: javassist.bytecode.BadBytecode: failed to resolve types
at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:169)
at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:108)
... 58 more
Caused by: javassist.NotFoundException: android.view.View$ScrollabilityCache
at javassist.ClassPool.get(ClassPool.java:452)
at javassist.bytecode.stackmap.TypeData$TypeVar.fixTypes2(TypeData.java:347)
at javassist.bytecode.stackmap.TypeData$TypeVar.fixTypes(TypeData.java:330)
at javassist.bytecode.stackmap.TypeData$TypeVar.dfs(TypeData.java:274)
at javassist.bytecode.stackmap.MapMaker.fixTypes(MapMaker.java:390)
at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:167)
... 59 more
,是Android API中的非公开课程。但我真正的单元测试(嘲弄Crosswalk的XWalkView,经过尝试here)显示了一个不同的类,最后一个“由...引起的”被
android.view.View.ScrollabilityCache
这让我觉得错误在Powermock的某个地方,无论是我使用它的方式(这是我第一次)还是在实现中。
这是我的Caused by: javassist.NotFoundException: android.view.View$AttachInfo
at javassist.ClassPool.get(ClassPool.java:452)
at javassist.bytecode.Descriptor.toCtClass(Descriptor.java:592)
at javassist.bytecode.Descriptor.getParameterTypes(Descriptor.java:439)
at javassist.CtBehavior.getParameterTypes(CtBehavior.java:298)
at javassist.CtBehavior.insertBefore(CtBehavior.java:749)
... 62 more
:
build.gradle
有关如何使用PowerMock和Robolectric成功模拟由XML布局文件引用的自定义视图的任何提示?