使用PowerMock和Robolectric

编程入门 行业动态 更新时间:2024-10-20 05:41:47
本文介绍了使用PowerMock和Robolectric - IncompatibleClassChangeError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我试图用PowerMockito嘲弄一些静态方法的Andr​​oid Robolectric测试。我使用JUnit 4.8.2,Robolectric 2.2的Mockito 1.9.5和1.9.5 PowerMock作为导演的这里。当我不得不使用RoboElectricTestRunner,我试图使用 PowerMockRule 来引导PowerMock。但是我得到一个不幸的 java.lang.IncompatibleClassChangeError 测试与PowerMock运行时。

  

java.lang.reflect.InvocationTargetException   在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)   在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)   在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)   在java.lang.reflect.Method.invoke(Method.java:597)   在sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:323)   在sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain(InstrumentationImpl.java:348)

     

致:java.lang.IncompatibleClassChangeError:实现类   在java.lang.ClassLoader.defineClass1(本机方法)   在java.lang.ClassLoader.defineClassCond(ClassLoader.java:637)   在需要java.lang.ClassLoader.defineClass(ClassLoader.java:621)   在java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)

如果我把 org.ow2.asm 的 org.powermock 库我收到后:

  

java.lang.IncompatibleClassChangeError:类org.objectweb.asm.tree.ClassNode有接口org.objectweb.asm.ClassVisitor作为超一流   在java.lang.ClassLoader.defineClass1(本机方法)   在java.lang.ClassLoader.defineClassCond(ClassLoader.java:637)   在需要java.lang.ClassLoader.defineClass(ClassLoader.java:621)   在java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)   在java.URLClassLoader.defineClass(URLClassLoader.java:283)   在java.URLClassLoader.access $ 000(URLClassLoader.java:58)   在java.URLClassLoader的$ 1.运行(URLClassLoader.java:197)   在java.security.AccessController.doPrivileged(本机方法)

上的每次的单元测试。

据Maven的depency:树Robolectric和PowerMock不共享任何依赖关系。 但是显然 org.powermock:powermock模块-javaagent 包一些组织/ ObjectWeb的/ ASM 类和Robolectric依靠组织。 ow2.asm:ASM:罐子:4.1 发生冲突

@RunWith(RobolectricTestRunner.class) @ prepareForTest(Helper.class) @PowerMockIgnore({com.sun.jmx。*,javax.management。*}) 公共类HelpFragTest {     @规则     公共PowerMockRule规则=新PowerMockRule();     静态{         PowerMockAgent.initializeIfNeeded();     }     FragmentActivity fragmentActivity;     FragmentManager fragmentManager;     ActionBarManager actionBarManager;     @之前     公共无效设置(){         actionBarManager =模拟(ActionBarManager.class);         。LowesApplication.instance()setActionBarManager(actionBarManager);         fragmentActivity = Robolectric.buildActivity(FragmentActivity.class).create()开始()恢复()得到()。;         fragmentManager = fragmentActivity.getSupportFragmentManager();     }     @测试     公共无效testShow(){         mockStatic(Helper.class);         HelpFrag helpFrag = HelpFrag.newInstance();         FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();         fragmentTransaction.add(helpFrag,NULL);         fragmentTransactionmit();         assertTrue(helpFrag.isVisible());     } }

解决方案

我找到了一种方法来使用PowerMock结合Robolectric。

在除了标准PowerMock罐子,所述PowerMock Junit的规则也是需要的。它被描述这里如何抓住它。我使用了 XStream的类加载版本,因为 objenesis 一个是非常错误。这正与PowerMock 1.5.5和Robolectric 2.3,我不能谈论的旧版本。同时请注意,Java代理不应包括在内,因为从我的经验,它引起的问题。

所以,如果你使用maven,这些依赖应该声明:

<依赖>     <的groupId> org.powermock< /的groupId>     < artifactId的> powermock模块,junit4< / artifactId的>     <版> $ {powermock.version}< /版本>     <范围>测试< /范围> < /依赖性> <依赖>     <的groupId> org.powermock< /的groupId>     < artifactId的> powermock模块-junit4规则< / artifactId的>     <版> $ {powermock.version}< /版本>     <范围>测试< /范围> < /依赖性> <依赖>     <的groupId> org.powermock< /的groupId>     < artifactId的> powermock-API的Mockito< / artifactId的>     <版> $ {powermock.version}< /版本>     <范围>测试< /范围> < /依赖性> <依赖>     <的groupId> org.powermock< /的groupId>     < artifactId的> powermock-类加载-XStream的< / artifactId的>     <版> $ {powermock.version}< /版本>     <范围>测试< /范围> < /依赖性>

然后,你必须设置你的测试类是这样的:

@RunWith(RobolectricTestRunner.class) @PowerMockIgnore({org.mockito。*,org.robolectric。*,机器人。*}) @ prepareForTest(Static.class) 公共类MyTest的{     @规则     公共PowerMockRule规则=新PowerMockRule();     私人MyActivity活动;     @之前     公共无效设置(){         活动= Robolectric.buildActivity(MyActivity.class).create()得到()。     }     @测试     公共无效测试()抛出异常{         PowerMockito.mockStatic(Static.class);         Mockito.when(Static.getCurrentTime())thenReturn(1)。         Assert.assertEquals(1,activity.getId());     } }

I'm trying to use PowerMockito to mock some static methods in Android Robolectric tests. I'm using JUnit 4.8.2, Robolectric 2.2, Mockito 1.9.5, and PowerMock 1.9.5 as directed here. As I have to use the RoboElectricTestRunner, I'm attempting to use the PowerMockRule to bootstrap PowerMock. However I'm getting an unfortunate java.lang.IncompatibleClassChangeError when the test with PowerMock runs.

java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:323) at sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain(InstrumentationImpl.java:348)

Caused by: java.lang.IncompatibleClassChangeError: Implementing class at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java:637) at java.lang.ClassLoader.defineClass(ClassLoader.java:621) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)

If I put org.ow2.asm after the org.powermock libraries I get:

java.lang.IncompatibleClassChangeError: class org.objectweb.asm.tree.ClassNode has interface org.objectweb.asm.ClassVisitor as super class at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java:637) at java.lang.ClassLoader.defineClass(ClassLoader.java:621) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141) at java.URLClassLoader.defineClass(URLClassLoader.java:283) at java.URLClassLoader.access$000(URLClassLoader.java:58) at java.URLClassLoader$1.run(URLClassLoader.java:197) at java.security.AccessController.doPrivileged(Native Method)

on every unit test.

According to Maven depency:tree Robolectric and PowerMock don't share any dependencies. But apparently org.powermock:powermock-module-javaagent packages some org/objectweb/asm classes, and Robolectric relies on org.ow2.asm:asm:jar:4.1 causing a conflict.

@RunWith(RobolectricTestRunner.class) @PrepareForTest(Helper.class) @PowerMockIgnore({"com.sun.jmx.*", "javax.management.*"}) public class HelpFragTest { @Rule public PowerMockRule rule = new PowerMockRule(); static { PowerMockAgent.initializeIfNeeded(); } FragmentActivity fragmentActivity; FragmentManager fragmentManager; ActionBarManager actionBarManager; @Before public void setup(){ actionBarManager = mock(ActionBarManager.class); LowesApplication.instance().setActionBarManager(actionBarManager); fragmentActivity = Robolectric.buildActivity(FragmentActivity.class).create().start().resume().get(); fragmentManager = fragmentActivity.getSupportFragmentManager(); } @Test public void testShow(){ mockStatic(Helper.class); HelpFrag helpFrag = HelpFrag.newInstance(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(helpFrag, null); fragmentTransactionmit(); assertTrue(helpFrag.isVisible()); } }

解决方案

I found a way to use PowerMock in conjunction with Robolectric.

In addition to the standard PowerMock jars, the PowerMock Junit Rule is also needed. It is described here how to grab it. I used the xstream classloading version, because the objenesis one is very buggy. This is working with PowerMock 1.5.5 and Robolectric 2.3, i cannot speak about the older versions. Also please note that the Java agent should not be included, because from my experience it causes problems.

So if you are using maven, these dependencies should be declared:

<dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>${powermock.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4-rule</artifactId> <version>${powermock.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito</artifactId> <version>${powermock.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-classloading-xstream</artifactId> <version>${powermock.version}</version> <scope>test</scope> </dependency>

Then you have to setup your test class like this:

@RunWith(RobolectricTestRunner.class) @PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" }) @PrepareForTest(Static.class) public class MyTest { @Rule public PowerMockRule rule = new PowerMockRule(); private MyActivity activity; @Before public void setup() { activity = Robolectric.buildActivity(MyActivity.class).create().get(); } @Test public void test() throws Exception { PowerMockito.mockStatic(Static.class); Mockito.when(Static.getCurrentTime()).thenReturn(1); Assert.assertEquals(1, activity.getId()); } }

更多推荐

使用PowerMock和Robolectric

本文发布于:2023-10-31 04:24:28,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1544994.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:PowerMock   Robolectric

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!