Tôi đã bắt đầu đánh một ClassCastException lạ trong Mockito khi sử dụng nó với Robolectric. Khi tôi chạy các bài kiểm tra tương tự không sử dụng Á hậu Robolectric, mọi thứ diễn ra tốt đẹp, không có ngoại lệ nào được ném ra.Mockito với Robolectric: "ClassCastException xảy ra khi tạo proxy"
Đây là stack trace:
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
Mã Tôi đang sử dụng như sau:
@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);
}
...
}
Đây là cách Robolectric Á hậu trông giống như:
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;
}
};
}
}
gì nên Tôi sửa chữa để loại bỏ ngoại lệ này?
Thú vị! Tôi đã đoán rằng có điều gì đó mâu thuẫn với Kotlin/Robolectric. Kotlin có thay thế ClassLoader không? Tôi hy vọng các chuyên gia Kotlin sẽ tham gia cuộc nói chuyện –
bạn có thể kiểm tra giải pháp từ đây https://github.com/robolectric/robolectric-gradle-plugin/issues/75 –
@EugenMartynov điểm tốt, tôi đã thêm "Kotlin" tag, có lẽ Kotlin mọi người sẽ giúp. –