使用Power Mock运行2个Roboelectic测试类并模拟相同的静态类时发生ClassCastException异常

kin*_*ana 1 java unit-testing powermock robolectric android-testing

我有2个测试类:MyTest1和MyTest2。它们都具有相同的标头并测试相同的类,但是它们测试该类的2个非常不同的方面(您可能会因此批评我,但让我们不在此讨论):

@RunWith(LocalRobolectricTestRunner.class)
@Config(manifest = RobolectricTestData.AndroidManifestFileName)
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })
@PrepareForTest(MyStrangeClassWithStaticMethods.class)
@ParametersAreNonnullByDefault
public class MyTest1 extends MyBaseTest {

    // This is to dinamically load PowerMock. We can't use PowerMockRunner because we already use
    // RobolectricTestRunner and PowerMockRunner doesn't do robolectric's stuff.
    @Rule
    public final PowerMockRule rule = new PowerMockRule();

    /**
     * Tests set up.
     */
    @Before
    public final void setUp() throws Exception {
        super.setUp();
    }
    public void testSomething() {
        PowerMockito.mockStatic(MyStrangeClassWithStaticMethods.class);
        // do some stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是我可以单独运行MyTest1并且所有测试都可以。我可以单独运行MyTest2,所有测试都可以。但是,当我同时运行MyTest1和MyTest2的所有测试(它们都编译到一个jar中)时,只有第一个运行类(MyTest1)可以正常运行,而第二个类则失败。所有测试都因以下异常而崩溃:

    org.mockito.exceptions.base.MockitoException: 
ClassCastException occurred while creating the mockito proxy :
  class to imposterize : 'com.my.project.MyStrangeClassWithStaticMethods', loaded by classloader : 'org.powermock.core.classloader.MockClassLoader@2617b42c'
  imposterizing class : 'com.my.project.MyStrangeClassWithStaticMethods$$EnhancerByMockitoWithCGLIB$$41f09512', loaded by classloader : 'org.mockito.internal.creation.jmock.SearchingClassLoader@230eec25'
  proxy instance class : 'com.my.project.MyStrangeClassWithStaticMethods$$EnhancerByMockitoWithCGLIB$$41f09512', loaded by classloader : 'org.mockito.internal.creation.jmock.SearchingClassLoader@23a0547b'

You might experience classloading issues, disabling the Objenesis cache *might* help (see MockitoConfiguration)
    at org.powermock.api.mockito.internal.mockcreation.MockCreator.createMethodInvocationControl(MockCreator.java:109)
    at org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:57)
    at org.powermock.api.mockito.PowerMockito.mockStatic(PowerMockito.java:70)
    at com.my.project.MyTest2.testSomething(MyTest2.java:66666<no matter what line number>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.powermock.modules.junit4.rule.PowerMockStatement$1.run(PowerMockRule.java:52)
    at sun.reflect.GeneratedMethodAccessor26.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    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:49)
    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:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.chromium.testing.local.GtestComputer$GtestSuiteRunner.run(GtestComputer.java:46)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:24)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
    at org.chromium.testing.local.JunitTestMain.main(JunitTestMain.java:105)
Caused by: java.lang.ClassCastException: Cannot cast com.my.project.MyStrangeClassWithStaticMethods$$EnhancerByMockitoWithCGLIB$$41f09512 to com.my.project.MyStrangeClassWithStaticMethods
    at java.lang.Class.cast(Class.java:3176)
    at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:62)
    ... 47 more
Run Code Online (Sandbox Code Playgroud)

这次崩溃迫使我将2个类合并为1个测试类。这可能阻止了我在另一个测试类中模拟MyStrangeClassWithStaticMethods.class的可能性。我只能嘲弄一次:(

当使用Power Mock对多个文件运行Robolectric测试时,该问题看起来像ClassCastException异常,但有点不同,需要另一个解决方案。

Powermock 1.6.0

Mockito 1.10.5

Robolectric 3.0

kin*_*ana 5

我找到了解决方案。堆栈跟踪显示:

禁用Objenesis缓存可能会有所帮助(请参阅MockitoConfiguration)

我做到了,它奏效了。只需将此类添加到测试源位置即可:

package org.mockito.configuration;

public class MockitoConfiguration extends DefaultMockitoConfiguration {
    @Override
    public boolean enableClassCache() {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 也解决了我的问题。起初,我不知道如何将文件放入正确的包中,如果其他人也遇到同样的问题:您应该自己在“ test.java”中创建一个包“ org.mockito.configuration”。...还有一种方法(非常简单)是在测试项目中的任意类中创建类,在顶部定义“ package org.mockito.configuration”,然后使用“移至软件包org.mockito.configuration”。 (3认同)