Class loading collision between Robolectric and Powermock

青春壹個敷衍的年華 提交于 2019-12-12 08:53:54

问题


I'm trying to write a test that needs both Robolectric 2.2 and PowerMock, as the code under test depends on some Android libraries and third party libraries with final classes that I need to mock.

Given that I'm forced to use the Robolectric test runner through:

@RunWith(RobolectricTestRunner.class)

...I cannot use the PowerMock test runner, so I'm trying to go with the PowerMock java agent alternative, without luck so far.

I have setup everything according to this guide but I'm facing a collision problem between classes required by the javaagent library and by robolectric through its dependency with asm-1.4. Both depend on

org.objectweb.asm.ClassVisitor

, but javaagent-1.5.1 ships with its own version where ClassVisitor is an interface while asm-1.4 version for the same namespace is an abstract class, with the corresponding error at runtime:

java.lang.IncompatibleClassChangeError: class org.objectweb.asm.tree.ClassNode has interface org.objectweb.asm.ClassVisitor as super class

I have even tried to modify the javaagent library jar to entirely remove the org.objectew.asm classes in there, but that doesn't work as ClassNotFoundException happens afterwards due to some other classes needed in the org.objectweb.asm package that only ship in the javaagent library jar, and not in the asm one.

Any ideas? According to examples out there the agent seems to work fine with, at least, the Spring test runner.


回答1:


I had the same problem and while I didn't solve this problem as such, I wanted to share my approach, which removes the need for PowerMock (which is always a good thing in my view): I wanted to mock a call to

Fragment fooFragment = new FooFragment();

So what I did was addanother level of indirection. I created a FragmentProvider class:

public FragmentFactory fragmentFactory = new FragmentFactory();
[...]
Fragment fooFragment = fragmentFactory.getFooFragment();

After i did this, I could just mock out the factory with standard Mockito, like this:

FragmentFactory mockFactory = mock(FragmentFactory.class);
activity.fragmentFactory = mockFactory;
when(mockFactory.getFooFragment()).thenReturn(mockFooFragment);


来源:https://stackoverflow.com/questions/19998398/class-loading-collision-between-robolectric-and-powermock

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!