问题
My Android project has several modules (one application and multiple libraries) and when I try to run all the unit tests (Robolectric 3.8) from the command line
./gradlew testDebugUnitTest
I get the following error (not when I run the same task from Android Studio)
java.lang.NoClassDefFoundError: android/content/Context at java.base/java.lang.Class.getDeclaredConstructors0(Native Method) at java.base/java.lang.Class.privateGetDeclaredConstructors(Class.java:3110) at java.base/java.lang.Class.getConstructor0(Class.java:3315) at java.base/java.lang.Class.getConstructor(Class.java:2108) at org.robolectric.RobolectricTestRunner.getHooksInterface(RobolectricTestRunner.java:473) at org.robolectric.RobolectricTestRunner.beforeTest(RobolectricTestRunner.java:308) at org.robolectric.internal.SandboxTestRunner$2.evaluate(SandboxTestRunner.java:241) at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:123) at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:42) 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.internal.SandboxTestRunner$1.evaluate(SandboxTestRunner.java:77) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:114) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:57) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:66) 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:564) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32) at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93) at com.sun.proxy.$Proxy1.processTestClass(Unknown Source) at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:108) 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:564) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:146) at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:128) at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63) at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55) at java.base/java.lang.Thread.run(Thread.java:844) Caused by: java.lang.ClassNotFoundException: couldn't load android.content.Context at org.robolectric.internal.bytecode.SandboxClassLoader.maybeInstrumentClass(SandboxClassLoader.java:174) at org.robolectric.internal.bytecode.SandboxClassLoader.lambda$findClass$0(SandboxClassLoader.java:133) at org.robolectric.util.PerfStatsCollector.measure(PerfStatsCollector.java:50) at org.robolectric.internal.bytecode.SandboxClassLoader.findClass(SandboxClassLoader.java:132) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:563) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496) ... 45 more Caused by: java.lang.IllegalArgumentException at org.objectweb.asm.ClassReader.(Unknown Source) at org.objectweb.asm.ClassReader.(Unknown Source) at org.robolectric.internal.bytecode.SandboxClassLoader$ClassInstrumentor.isOverridingFinalMethod(SandboxClassLoader.java:502) at org.robolectric.internal.bytecode.SandboxClassLoader$ClassInstrumentor.instrumentInheritedObjectMethod(SandboxClassLoader.java:523) at org.robolectric.internal.bytecode.SandboxClassLoader$ClassInstrumentor.instrument(SandboxClassLoader.java:395) at org.robolectric.internal.bytecode.SandboxClassLoader$InvokeDynamicClassInstrumentor.instrument(SandboxClassLoader.java:1274) at org.robolectric.internal.bytecode.SandboxClassLoader.getInstrumentedBytes(SandboxClassLoader.java:271) at org.robolectric.internal.bytecode.SandboxClassLoader.lambda$maybeInstrumentClass$1(SandboxClassLoader.java:166) at org.robolectric.util.PerfStatsCollector.measure(PerfStatsCollector.java:50) at org.robolectric.internal.bytecode.SandboxClassLoader.maybeInstrumentClass(SandboxClassLoader.java:165) ... 50 more
The build.gradle file on each module contains the following configuration
testOptions {
unitTests {
returnDefaultValues true
}
}
The application module defines a couple of flavours all running in the same dimension
flavorDimensions 'default'
Any idea?
回答1:
I have that kind of (not same)error before. I think NoClassDefFoundError is telling you that your Android application is running on a different version of android like 32bit or 64 bit you need to add jniLibs folder in the android project.
That get your library according to a device at runtime.
Search about JniLibs about more.
Thanks!!
回答2:
It has to be with your dependencies. You have to put the dependencies you use with testImplementation
.
For example, I was getting the error having this dependency defined:
compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.2"
Now I've added the other one:
//Used to compile
compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.2"
//Used to compile tests
testImplementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.2"
Check what dependency you are missing running
./gradlew test --stacktrace
Gradle will automatically generate html with all the trace organized.
It's just a possibility, let me know if it works.
UPDATE: This work only if you use compileOnly
with the missed dependencies. The reason is that compileOnly
declares dependencies only used at compilation time, so we need testImplementation
also. Another solution would be to directly use implementation
which would add the requires dependencies (so we wouldn't need testImplementation
).
来源:https://stackoverflow.com/questions/50985554/noclassdeffounderror-while-running-unit-tests-with-roboelectric-3-8