I am trying to run Android unit tests with Robolectric so I can access contexts in a multi-dex application. This is my build.gradle:
implementation 'androidx.test.ext:junit:1.1.5'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-core:3.2.0'
testImplementation 'org.robolectric:robolectric:4.9'
testImplementation "org.robolectric:shadows-multidex:3.0"
testImplementation 'androidx.test:core:1.5.0'
When I try to run the tests I get the following error message during initialization:
Receiver class org.robolectric.shadows.multidex.Shadows does not define or inherit an implementation of the resolved method 'abstract java.util.Collection getShadows()' of interface org.robolectric.internal.ShadowProvider.
java.lang.AbstractMethodError: Receiver class org.robolectric.shadows.multidex.Shadows does not define or inherit an implementation of the resolved method 'abstract java.util.Collection getShadows()' of interface org.robolectric.internal.ShadowProvider.
at org.robolectric.internal.bytecode.ShadowMap.createFromShadowProviders(ShadowMap.java:42)
at org.robolectric.internal.bytecode.ShadowProviders.<init>(ShadowProviders.java:28)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at org.robolectric.util.inject.Injector.inject(Injector.java:250)
at org.robolectric.util.inject.Injector.lambda$memoized$1(Injector.java:232)
at org.robolectric.util.inject.Injector$MemoizingProvider.get(Injector.java:498)
at org.robolectric.util.inject.Injector.getInstanceInternal(Injector.java:224)
at org.robolectric.util.inject.Injector.getInstance(Injector.java:208)
at org.robolectric.util.inject.Injector.getInstance(Injector.java:202)
at org.robolectric.internal.SandboxTestRunner.<init>(SandboxTestRunner.java:79)
at org.robolectric.RobolectricTestRunner.<init>(RobolectricTestRunner.java:106)
at org.robolectric.RobolectricTestRunner.<init>(RobolectricTestRunner.java:101)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:37)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
at org.junit.internal.requests.ClassRequest.createRunner(ClassRequest.java:28)
at org.junit.internal.requests.MemoizingRequest.getRunner(MemoizingRequest.java:19)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:78)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Can anyone help me with this? Do we even need Robolectric for this anymore or does androidx finally allow testing of contexts?
Why
org.robolectric:shadows-multidex:jar:3.0
, if you are usingorg.robolectric:robolectric:jar:4.9
?You might consider instead
org.robolectric:shadows-multidex:jar:4.9
.Such a difference in version could explain the
java.lang.AbstractMethodError
you are seeing.That error is pointing to a mismatch between the implementation of a method in a class and the declaration of that method in an interface that the class is supposed to implement. Specifically, it is stating that the
org.robolectric.shadows.multidex.Shadows
class does not have a correct implementation for thegetShadows()
method declared in theorg.robolectric.internal.ShadowProvider
interface.Using a compatible version should help resolve that error.
The corrected
build.gradle
file would then be:If you see a
java.lang.NoClassDefFoundError: androidx/multidex/MultiDexApplication
error, it means theMultiDexApplication
class could not be found during runtime.You may need to add the multidex library to your dependencies.