使用Roboelectric 3.8运行单元测试时出现NoClassDefFoundError

时间:2018-06-22 10:03:52

标签: android gradle robolectric

我的Android项目有多个模块(一个应用程序和多个库),当我尝试从命令行运行所有单元测试( Robolectric 3.8

./gradlew testDebugUnitTest

我收到以下错误(不是当我从Android Studio运行相同任务时出现)

  

java.lang.NoClassDefFoundError:android / content / Context位于   java.base / java.lang.Class.getDeclaredConstructors0(本机方法)位于   java.base / java.lang.Class.privateGetDeclaredConstructors(Class.java:3110)     在java.base / java.lang.Class.getConstructor0(Class.java:3315)在   java.base / java.lang.Class.getConstructor(Class.java:2108)在   org.robolectric.RobolectricTestRunner.getHooksInterface(RobolectricTestRunner.java:473)     在   org.robolectric.RobolectricTestRunner.beforeTest(RobolectricTestRunner.java:308)     在   org.robolectric.internal.SandboxTestRunner $ 2.evaluate(SandboxTestRunner.java:241)     在   org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:123)     在   org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:42)     在org.junit.runners.ParentRunner处$ 3.run(ParentRunner.java:290)在   org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:71)在   org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)在   org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:58)在   org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:268)在   org.robolectric.internal.SandboxTestRunner $ 1.evaluate(SandboxTestRunner.java:77)     在org.junit.runners.ParentRunner.run(ParentRunner.java:363)处   org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:114)     在   org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:57)     在   org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:66)     在   org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)     在   java.base / jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(本机   方法)   java.base / jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)     在   java.base / jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     在java.base / java.lang.reflect.Method.invoke(Method.java:564)在   org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)     在   org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)     在   org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)     在   org.gradle.internal.dispatch.ProxyDispatchAdapter $ DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)     在com.sun.proxy。$ Proxy1.processTestClass(未知源)处   org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:108)     在   java.base / jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(本机   方法)   java.base / jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)     在   java.base / jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     在java.base / java.lang.reflect.Method.invoke(Method.java:564)在   org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)     在   org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)     在   org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection $ DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:146)     在   org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection $ DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:128)     在   org.gradle.internal.remote.internal.hub.MessageHub $ Handler.run(MessageHub.java:404)     在   org.gradle.internal.concurrent.ExecutorPolicy $ CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)     在   org.gradle.internal.concurrent.ManagedExecutorImpl $ 1.run(ManagedExecutorImpl.java:46)     在   java.base / java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)     在   java.base / java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:641)     在   org.gradle.internal.concurrent.ThreadFactoryImpl $ ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)     在java.base / java.lang.Thread.run(Thread.java:844)造成原因:   java.lang.ClassNotFoundException:无法加载   android.content.Context在   org.robolectric.internal.bytecode.SandboxClassLoader.maybeInstrumentClass(SandboxClassLoader.java:174)     在   org.robolectric.internal.bytecode.SandboxClassLoader.lambda $ findClass $ 0(SandboxClassLoader.java:133)     在   org.robolectric.util.PerfStatsCollector.measure(PerfStatsCollector.java:50)     在   org.robolectric.internal.bytecode.SandboxClassLoader.findClass(SandboxClassLoader.java:132)     在java.base / java.lang.ClassLoader.loadClass(ClassLoader.java:563)     在java.base / java.lang.ClassLoader.loadClass(ClassLoader.java:496)     ... 45更多原因于:java.lang.IllegalArgumentException   org.objectweb.asm.ClassReader。(来源未知)   org.objectweb.asm.ClassReader。(来源未知)   org.robolectric.internal.bytecode.SandboxClassLoader $ ClassInstrumentor.isOverridingFinalMethod(SandboxClassLoader.java:502)     在   org.robolectric.internal.bytecode.SandboxClassLoader $ ClassInstrumentor.instrumentInheritedObjectMethod(SandboxClassLoader.java:523)     在   org.robolectric.internal.bytecode.SandboxClassLoader $ ClassInstrumentor.instrument(SandboxClassLoader.java:395)     在   org.robolectric.internal.bytecode.SandboxClassLoader $ InvokeDynamicClassInstrumentor.instrument(SandboxClassLoader.java:1274)     在   org.robolectric.internal.bytecode.SandboxClassLoader.getInstrumentedBytes(SandboxClassLoader.java:271)     在   org.robolectric.internal.bytecode.SandboxClassLoader.lambda $ maybeInstrumentClass $ 1(SandboxClassLoader.java:166)     在   org.robolectric.util.PerfStatsCollector.measure(PerfStatsCollector.java:50)     在   org.robolectric.internal.bytecode.SandboxClassLoader.maybeInstrumentClass(SandboxClassLoader.java:165)     ...另外50个

每个模块上的 build.gradle 文件包含以下配置

testOptions {
    unitTests {
        returnDefaultValues true
    }
}

应用程序模块定义了两个风味,它们都在同一维度上运行

flavorDimensions 'default'

有什么主意吗?

2 个答案:

答案 0 :(得分:4)

我以前有这种(不同)错误。我认为 NoClassDefFoundError 告诉您,您的Android应用程序正在其他版本的android(例如32位或64位)上运行,您需要在android项目中添加 jniLibs 文件夹。

这会在运行时根据设备获取您的库。

搜索有关JniLib的更多信息。

谢谢!

答案 1 :(得分:0)

它必须与您的依赖项有关。您必须放置与testImplementation一起使用的依赖项。

例如,在定义此依赖项时出现错误:

compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.2"

现在我添加了另一个:

//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"

检查您缺少运行的依赖项

  

./ gradlew测试--stacktrace

Gradle会自动生成包含所有跟踪的html。

这只是一种可能性,让我知道它是否有效。

更新:仅当您将compileOnly与缺少的依赖项一起使用时,此功能才有效。原因是compileOnly声明了仅在编译时使用的依赖项,因此我们也需要testImplementation。另一个解决方案是直接使用implementation,它会添加require依赖项(因此我们不需要testImplementation)。