Android jUnit测试java.lang.NoClassDefFoundError: android/database/sqlite/SQLiteOpenHelper。

19

我正在尝试运行一个单元测试,模拟SQLiteOpenHelper的子类,但是我得到了以下错误。

java.lang.NoClassDefFoundError: android/database/sqlite/SQLiteOpenHelper

    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    ...
at org.dfhu.vpodplayer.util.JsonExporterTest.export(JsonExporterTest.java:43)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    ...

我的Gradle文件看起来像

apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion '25.0.1'
    defaultConfig {
        applicationId "org.dfhu.vpodplayer"
        minSdkVersion 18
        targetSdkVersion 24
        versionCode 1
        versionName "1.2"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        targetCompatibility 1.7
        sourceCompatibility 1.7
    }
}


buildscript {
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
  }
}

apply plugin: 'com.neenbedankt.android-apt'

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })

    compile 'com.android.support:appcompat-v7:24.2.1'
    compile 'com.android.support:support-v4:24.2.1'
    compile 'com.android.support:recyclerview-v7:24.2.1'

    testCompile 'junit:junit:4.12'
    testCompile 'org.powermock:powermock-api-mockito:1.6.5'
    testCompile 'org.powermock:powermock-module-junit4:1.6.5'
}

在重新安装Android Studio并更新builtToolsVersion至'25.0.1'之后,此方法曾经有效。

我正在寻找一种方法,在我的测试运行程序中获取我的android依赖关系。


5
它能与 ./gradlew test 一起运行吗? - tynn
2
@tynn 是的,看起来它可以工作了,它下载了一堆依赖项,现在也可以在Android Studio中工作了。我以为在Android Studio侧边栏中点击“Gradle > [MyProjectsName] > Verification > test”与CLI是相同的,但我想有些不同。如果您将此发布为答案,我会+1并检查正确性。 - Victory
1
谢谢@tynn,对我有用。现在也可以从AS中工作了。 - Pavel Biryukov
6个回答

24

有时候Android Studio在测试中无法正确加载Android类到类路径中。在我们的情况下,这通常是指android.os.Parcelable。但是CI总是正常工作的。

因此,在这种情况下运行./gradlew test应该总是有效的,并且有些运气的话可以修复Android Studio的依赖关系问题。


谢谢你的建议,对我来说,这似乎是Android Studio的一个bug。 - Victory
1
无法验证。不过 CI 有帮助。 - tynn
在我翻来覆去地搜索在线帮助一个小时后,你的解决方案真是救了我的一天。 - Ewoks
谢谢你的回答。这对我有用。这很可能是由于缺少依赖项而发生的。一旦你从终端运行它并下载依赖项,测试也可以从Android Studio开始工作。 - Abhinav Manchanda
@Abhinav,这是因为你的工作空间中缺少mockable-android-XX.jar文件所致。请查看我的答案这里,其中解释了如何解决这个问题。 - Adil Hussain
如果使用不同的Gradle守护程序,则此操作可能无法解决依赖项问题;如果使用相同的守护程序,则此操作可能永远无法正常工作。 - Amit Kaushik

15

这个问题困扰我已经有一段时间了,让我非常愤怒。现在我终于搞清楚它的根源了!

首先需要注意的是,在你的项目中运行以下命令后...

gradle clean build

如果一切顺利,你的工作空间中将会出现一个名为build/generated/mockable-android-XX.jar的文件。该文件由mockableAndroidJar Gradle任务生成,在testbuild Gradle任务的执行过程中被调用。

当该文件从工作空间中消失时,问题就出现了。不幸的是,Gradle错误地估计mockableAndroidJar任务已经是最新的并因此跳过了它的执行。你可以通过运行以下命令来验证这一点...

gradle mockableAndroidJar --info

...你会看到以下类似的信息...

Skipping task ':Android:mockableAndroidJar' as it is up-to-date (took 0.001 secs).

解决方法是强制运行mockableAndroidJar Gradle任务,您可以通过运行以下命令来执行...

解决方法是强制运行mockableAndroidJar Gradle任务,您可以通过运行以下命令来执行...

gradle mockableAndroidJar --rerun-tasks

...然后Voila,您现在应该可以在您的工作区中再次看到build/generated/mockable-android-XX.jar文件了,这样您的Android单元测试将重新运行。


1
Rafael,mockableAndroidJar Gradle任务可能已经在最近的Android Plugin for Gradle版本中得到修复,所以该任务现在可能更好地确定是否缺少mockable-android-XX.jar文件。如果是这种情况,那么是的,添加--rerun-tasks选项可能不再必要。 - Adil Hussain
3
似乎mockableAndroidJar已被重命名为createMockableJar。请见:https://dev59.com/kq_la4cB1Zd3GeqPs3DX#53632603 - Michał Klimczak

8

今天我遇到了这个问题,现在我想分享一下我的解决方法。

请在您的 build.gradle 文件中添加以下内容:

android {
...

testOptions {
        unitTests.returnDefaultValues = true
    }
}

重新同步gradle文件。现在应该可以工作了,并且mockable android jar文件应该已经生成。

如果您的gradle文件中没有testOptions,请将其删除并重新同步。

希望这有所帮助。


1
确实有帮助,不错。 - D.Rosado

5

您还可以在“文件”菜单下的工作室中尝试“使缓存无效并重新启动”选项。


3
对于我的情况,我只需运行Gradle任务中的“test”任务,它会还原一切。 enter image description here

2

在我的情况下,问题是通过清除 app/build 目录解决的。我不知道为什么,但由于某种原因,gradle clean 命令没有完成这个步骤,所以我必须手动处理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接