bolectric测试时发生ClassCastException

bolectric测试时发生ClassCastException

本文介绍了使用Power Mock在多个文件上运行Robolectric测试时发生ClassCastException异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我根据参考指南设置了电源模拟。单个测试类似乎一切运行良好。但是当执行多个JUnit测试时,我在第二个测试类上遇到了以下错误。

So I set up the power mock based on the reference guide here. It all seems to run perfectly fine with a single test class. But when executing multiple JUnit tests I am getting the following error on the second test class.

从下面的stacktrace中可以看到,我正在尝试模拟otto总线实例。在第一个测试类上它似乎可以正确模拟,但是在第二个类上,我得到了该类强制转换异常。

As you can see from the stacktrace below I am trying to mock a otto Bus instance. It seemed to mock properly on the first test class but on the the second class I am getting this class cast exception.

在stacktrace上,我得到了禁用Objenisis缓存的建议但是我不确定如何完成此操作,如果我使用classloading-xstream:1.6.2(根据上面附加的Robolectric Wiki链接)确实是根本原因,那么,就可以了。

On the stacktrace I am getting suggestion to disable Objenisis cache but I am not sure how to accomplish that and if that is actually the root cause as I am using classloading-xstream:1.6.2 as per the Robolectric Wiki link attached above.

问题是,如果我运行一个JUnit测试类,则我的设置运行良好,但是一旦我尝试在一个包中运行所有测试,则只有第一个测试可以工作,而随后的测试将获得类强制转换异常。

The thing is my setup works well if I run a single JUnit test class, but once I try to run all the tests in a package only the first test will work and subsequent tests will get the class cast exception.

org.mockito.exceptions.base.MockitoException:
    ClassCastException occurred while creating the mockito proxy :
      class to mock : 'com.squareup.otto.Bus', loaded by classloader : 'org.robolectric.internal.bytecode.InstrumentingClassLoader@1593948d'
      created class : 'com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196', loaded by classloader : 'org.robolectric.internal.bytecode.InstrumentingClassLoader@1593948d'
      proxy instance class : 'com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196', loaded by classloader : 'org.mockito.internal.creation.util.SearchingClassLoader@618ff5c2'
      instance creation by : ObjenesisInstantiator

    You might experience classloading issues, disabling the Objenesis cache *might* help (see MockitoConfiguration)
        at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:61)
        at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:49)
        at org.powermock.api.mockito.repackaged.CglibMockMaker.createMock(CglibMockMaker.java:24)
        at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:45)
        at com.acme.android.myapp.services.gcm.handlers.RequestLogoutHandlerTest.setup(RequestLogoutHandlerTest.java:39)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        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.RunBefores.evaluate(RunBefores.java:24)
        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.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:27)
        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.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:62)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
    Caused by: java.lang.ClassCastException: Cannot cast com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196 to com.squareup.otto.Bus
        at java.lang.Class.cast(Class.java:3369)
        at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:59)
        at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:49)
        at org.powermock.api.mockito.repackaged.CglibMockMaker.createMock(CglibMockMaker.java:24)
        at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:45)
        at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33)
        at org.mockito.internal.MockitoCore.mock(MockitoCore.java:59)
        at org.mockito.Mockito.mock(Mockito.java:1285)
        at org.mockito.Mockito.mock(Mockito.java:1163)
        ... 36 more


    org.mockito.exceptions.base.MockitoException:
    ClassCastException occurred while creating the mockito proxy :
      class to mock : 'com.squareup.otto.Bus', loaded by classloader : 'org.robolectric.internal.bytecode.InstrumentingClassLoader@1593948d'
      created class : 'com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196', loaded by classloader : 'org.robolectric.internal.bytecode.InstrumentingClassLoader@1593948d'
      proxy instance class : 'com.squareup.otto.Bus$$EnhancerByMockitoWithCGLIB$$82a3b196', loaded by classloader : 'org.mockito.internal.creation.util.SearchingClassLoader@618ff5c2'
      instance creation by : ObjenesisInstantiator

    You might experience classloading issues, disabling the Objenesis cache *might* help (see MockitoConfiguration)
        at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:61)
        at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:49)
        at org.powermock.api.mockito.repackaged.CglibMockMaker.createMock(CglibMockMaker.java:24)
        at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:45)
        at com.acme.android.myapp.services.gcm.handlers.RequestLogoutHandlerTest.setup(RequestLogoutHandlerTest.java:39)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        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.RunBefores.evaluate(RunBefores.java:24)
        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.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:27)
        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.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:6


推荐答案

我建议按照异常消息
中的建议禁用Mockito的ClassCache。
这是我如何通过在Android Studio中添加MockitoConfiguration类来禁用Mockito ClassCache。

I would suggest to disable ClassCache of Mockito as suggested in the exception message.Here is how I disable Mockito ClassCache by adding a MockitoConfiguration class in Android Studio.


  1. 在您的单元测试目录下src / test / java,创建一个与Mockito配置包org / mockito / configuration完全相同的包目录。

  1. Under your unit test directory, src/test/java, create a package directory that is exactly the same as Mockito configuration package, org/mockito/configuration.

因此在完整测试下在src / test / java / org / mockito / configuration目录中,添加一个名为MockitoConfiguration的新类。

So under the full test directory src/test/java/org/mockito/configuration, add a new class named MockitoConfiguration.

按如下所示覆盖enableClassCache()方法。

Overwrite the enableClassCache() method as following.

package org.mockito.configuration;

    public class MockitoConfiguration extends DefaultMockitoConfiguration {

    @Override
    public boolean enableClassCache() {
        return false;
    }
}


  • 在src下运行单元测试时/ java / test,应该加载MockitoConfiguration并禁用Mockito类缓存。

  • When you run your Unit test under src/java/test, your MockitoConfiguration should be loaded and Mockito class cache should be disabled.

    希望它会有所帮助。

    这篇关于使用Power Mock在多个文件上运行Robolectric测试时发生ClassCastException异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

  • 09-02 14:57