ClassCastException:NoClassDefFoundError不能转换为RuntimeException?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (62)

我正在将我的代码库升级到Gradle 2.2和Android Studio 1.0。我目前正试图让Robolectric 2.4工作,但是当我尝试运行单元测试时遇到了一个奇怪的问题。这个问题只发生在a后gradle clean; 多次运行测试套件将产生通过测试(如预期的那样)。当我在清理后运行测试时,出现以下错误:

java.lang.ClassCastException: java.lang.NoClassDefFoundError cannot be cast to java.lang.RuntimeException

我已将错误追溯到此调用:

Activity activity = Robolectric.setupActivity(MainActivity.class);

无论使用Robolectric gradle插件(org.robolectric:robolectric-gradle-plugin:0.14.0)还是JC和K Android单元测试插件(com.github.jcandksolutions.gradle:android-unit-test:2.1.1),我都会遇到此错误。

我在Robolectric Github上发现了这个问题,但它看起来并没有被解决:https//github.com/robolectric/robolectric/issues/1385

这个问题也在android studio单元测试插件中引用,在'Trouble Shooting'中:https//github.com/evant/android-studio-unit-test-plugin

我目前的示例代码在这里:https//github.com/KioKrofovitch/robolectric-upgrade-test

尽管api-android-19和api-android-21项目由于其他原因失败,我已经能够在Robolectric示例上运行api-android-16项目而不会看到这个问题。我看不出他们做得有什么不同,这样他们就不会失败。 https://github.com/robolectric/robolectric-samples

有没有人找到解决这个问题的方法?两次运行测试对于Jenkins或Travis等CI工具来说不是一个很好的解决方法。

嵌入代码示例

我添加JC和K单元测试库的顶层build.gradle:

buildscript {
    repositories {
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.0.0'
        classpath 'com.github.jcandksolutions.gradle:android-unit-test:2.1.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

我的项目级别build.gradle,我在robolectric中添加:

apply plugin: 'com.android.application'

repositories {
    mavenCentral()
}

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.example.robolectrictest"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }

        androidTest {
            setRoot('src/androidTest')
        }
    }
}

// Must be after Android plugin
apply plugin: 'android-unit-test'

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'

    //androidTestCompile 'junit:junit:4.10'
    //androidTestCompile 'org.robolectric:robolectric:2.4'

    // Testing frameworks
    testCompile 'junit:junit:4.10'
    testCompile 'org.robolectric:robolectric:2.4'
}

我非常基本的活动,一切都留在模板创建它:

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

我的虚拟测试,由于setupActivity()方法错误,无法访问我的断言:

@Config(emulateSdk = 18)
@RunWith(RobolectricTestRunner.class)

public class ApplicationTest {

    @org.junit.Test
    public void testDummy() throws Exception {

        Activity activity = Robolectric.setupActivity(MainActivity.class);

        assertTrue(true);
    }

}

要运行测试,我从我的项目的顶级目录调用以下命令:

./gradlew clean
./gradlew test

我也尝试在gradle包装外运行测试,并得到相同的结果

gradle clean
gradle test
提问于
用户回答回答于

这被确认为Robolectric 2.4的一个问题(问题#1385)。Erich Douglass今天已经解决了这个问题,并提出以下评论:

我们正在研究3.0的appcompat支持。在此之前,你可以做的事情不多。

https://github.com/robolectric/robolectric/issues/1385

所以直到3.0发布之前,我将使用以下解决方法:

./gradlew clean
./gradlew assemble
./gradlew test

组装完成后,它创建了Robolectric显然需要的所有项目。然后你可以成功地运行你的测试。这个解决方案比只运行./gradlew build./gradlew test两次更好,因为它可以在本地以及像Travis或Jenkins这样的CI工具上实现。在Jenkins中运行多个Gradle任务的语法是在每个任务之间留下一个空格:

assemble test

扫码关注云+社区