java - 带有 Robolectric 的 Mockito : "ClassCastException occurred when creating the proxy"

标签 java android mockito robolectric

在将 Mockito 与 Robolectric 一起使用时,我开始在 Mockito 中遇到一个奇怪的 ClassCastException。当我不使用 Robolectric runner 运行相同的测试时,一切正常,没有抛出异常。

这是堆栈跟踪:

org.mockito.exceptions.base.MockitoException: 
ClassCastException occurred when creating the proxy.
You might experience classloading issues, disabling the Objenesis cache *might* help (see MockitoConfiguration)
    at com.compassrosetech.ccs.android.test.ObservableCacheDispatcherTest.setUp(ObservableCacheDispatcherTest.java:63)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:236)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:158)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.lang.ClassCastException: kotlin.Function0$$EnhancerByMockitoWithCGLIB$$c0163e7f cannot be cast to org.mockito.cglib.proxy.Factory
    at org.mockito.internal.creation.jmock.ClassImposterizer.createProxy(ClassImposterizer.java:128)
    at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:63)
    at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:56)
    at org.mockito.internal.creation.CglibMockMaker.createMock(CglibMockMaker.java:23)
    at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:26)
    at org.mockito.internal.MockitoCore.mock(MockitoCore.java:51)
    at org.mockito.Mockito.mock(Mockito.java:1243)
    at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:30)
    at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:16)
    at org.mockito.internal.configuration.DefaultAnnotationEngine.createMockFor(DefaultAnnotationEngine.java:43)
    at org.mockito.internal.configuration.DefaultAnnotationEngine.process(DefaultAnnotationEngine.java:66)
    at org.mockito.internal.configuration.InjectingAnnotationEngine.processIndependentAnnotations(InjectingAnnotationEngine.java:71)
    at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:55)
    at org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:108)
    ... 29 more

我使用的代码如下:

@RunWith(ApplicationTestRunner.class)
public class ObservableCacheDispatcherTest {

    @Mock
    private IDataMapper mockDataMapper;

    @Mock
    private ICache mockCache;

    @Mock
    private Function0<Object> mockLoader;

    private ObservableCacheDispatcher cacheDispatcher;


    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this); // <-- exception happens when executing this statement
        cacheDispatcher = new ObservableCacheDispatcher(mockCache, mockDataMapper);
    }

    ...
}

这是 Robolectric 运行者的样子:

public class ApplicationTestRunner extends RobolectricTestRunner {

    //Maximun SDK Robolectric will compile (issues with SDK > 18)
    private static final int MAX_SDK_SUPPORTED_BY_ROBOLECTRIC = 18;

    private static final String ANDROID_MANIFEST_PATH = "../app/src/main/AndroidManifest.xml";
    private static final String ANDROID_MANIFEST_RES_PATH = "../app/src/main/res";

    /**
     * Call this constructor to specify the location of resources and AndroidManifest.xml.
     *
     * @throws org.junit.runners.model.InitializationError
     */
    public ApplicationTestRunner(Class<?> testClass) throws InitializationError {
        super(testClass);
    }

    @Override protected AndroidManifest getAppManifest(Config config) {
        return new AndroidManifest(Fs.fileFromPath(ANDROID_MANIFEST_PATH),
                Fs.fileFromPath(ANDROID_MANIFEST_RES_PATH)) {
            @Override
            public int getTargetSdkVersion() {
                return MAX_SDK_SUPPORTED_BY_ROBOLECTRIC;
            }
        };
    }
}

我应该如何修复才能摆脱这个异常?

最佳答案

按照建议

'disabling the Objenesis cache might help'

您可以创建覆盖 MockitoConfiguration。
为此

  • 在你的 src/test/java 下创建一个名为 org.mockito.configuration 的包
  • 编写 MockitoConfiguration 类

类文件

package org.mockito.configuration;

public class MockitoConfiguration extends DefaultMockitoConfiguration {

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

再次尝试构建您的代码。

关于java - 带有 Robolectric 的 Mockito : "ClassCastException occurred when creating the proxy",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29072148/

相关文章:

java - 从对象 vector 中获取 int

安卓磨损 : launching an activty in the handheld on clicking notification action button in wear

java - 检查特定对象属性值时的 Mockito

c# - 以下方法或属性之间的调用不明确 : `Android. App.AlertDialog.Builder.SetPositiveButton

java - 单元 : How to write test case using jUnit and Mockito

java - 如果调用某个类的对象的方法,则 Mockito doReturn

java - gson解析来自google矩阵api的嵌套json对象

java - 如何使下面的java类不可变

java - 我在哪里可以找到 RCP 产品中的系统输出打印件?

Android gradle google-services 构建失败 "Duplicate Entry"