本文介绍了使用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运行时。

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

上的每次的单元测试。

据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);        fragmentTransaction.commit();        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.

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

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);
        fragmentTransaction.commit();

        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 - IncompatibleClassChangeError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-16 05:16