Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 在多个文件上使用Power Mock运行Robolectric测试时发生ClassCastException异常_Unit Testing_Robolectric_Powermock_Android Testing_Powermockito - Fatal编程技术网

Unit testing 在多个文件上使用Power Mock运行Robolectric测试时发生ClassCastException异常

Unit testing 在多个文件上使用Power Mock运行Robolectric测试时发生ClassCastException异常,unit-testing,robolectric,powermock,android-testing,powermockito,Unit Testing,Robolectric,Powermock,Android Testing,Powermockito,因此,我根据参考指南建立了powermock。使用一个测试类,一切似乎都运行得很好。但是,当执行多个JUnit测试时,我在第二个测试类上遇到以下错误 从下面的stacktrace中可以看到,我试图模拟一个otto总线实例。在第一个测试类上,它似乎进行了适当的模拟,但在第二个类上,我得到了这个类强制转换异常 在stacktrace上,我得到了禁用Objenisis缓存的建议,但我不确定如何做到这一点,也不确定这是否是根本原因,因为我正在使用classloading xstream:1.6.2,正如

因此,我根据参考指南建立了powermock。使用一个测试类,一切似乎都运行得很好。但是,当执行多个JUnit测试时,我在第二个测试类上遇到以下错误

从下面的stacktrace中可以看到,我试图模拟一个otto总线实例。在第一个测试类上,它似乎进行了适当的模拟,但在第二个类上,我得到了这个类强制转换异常

在stacktrace上,我得到了禁用Objenisis缓存的建议,但我不确定如何做到这一点,也不确定这是否是根本原因,因为我正在使用classloading xstream:1.6.2,正如上面附加的Robolectric Wiki链接所示

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

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

所以我通过添加

@PowerMockIgnore({ "*.*" }) 
@PrepareForTest({ StaticClass1.class,StaticClass2.class })

这将使Power mock忽略所有类。在我的例子中,PowerMock正在类加载总线,而在我的代码中,总线实际上是由Mockito模拟的

我建议按照异常消息中的建议禁用Mockito的类缓存 . 下面是我如何通过在androidstudio中添加MockitoConfiguration类来禁用Mockito类缓存的

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

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

  • 覆盖enableClassCache()方法,如下所示

    package org.mockito.configuration;
    
        public class MockitoConfiguration extends DefaultMockitoConfiguration {
    
        @Override
        public boolean enableClassCache() {
            return false;
        }
    }
    
  • 当您在src/java/test下运行单元测试时,应该加载Mockito配置并禁用Mockito类缓存


  • 希望能有所帮助。

    在某些情况下,这可能会起作用,但如果您有一套混合使用PowerMockito和Mockito的测试,我发现这样做会有问题。在使用PowerMockito的测试中,使用MockitoConfiguration类和@PowerMockIgnore({“org.mockito.*})组合答案对我来说很有用。谢谢