How to run unit tests with dependency to an Android library module?

落爺英雄遲暮 提交于 2019-12-04 01:48:52

问题


Whenever I try to run unit-tests for classes in my app module that depend on classes from an library module, I get this:

java.lang.NoClassDefFoundError: de/ivu/junittest/DummyData
    at de.ivu.junittest.app.DummyModel.<init>(DummyModel.java:16)
    at DummyModelTest.testInstantiation(DummyModelTest.java:7)
    ...

In the above sample, DummyData is part of the lib module, while DummyModel is part of the app module. DummyModel has a member of type DummyData, but instantiating this in the test-class DummyModelTest causes the aforementioned exception at test-time.

The project structure is as follows:

JUnitTestProject
    app [module]
         src
             main
                 java
                     de.ivu.junittest.app
                         DummyModel.java
                         ...
                 ...
             test
                 java
                     de.ivu.junittest.app
                         DummyModelTest.java
                 ...
    lib [module]
         src
             main
                 java
                     de.ivu.junittest
                         DummyData.java
                         ...
                 ...

The build.gradle for the app module contains the following:

apply plugin: 'android'

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.1"

    defaultConfig {
        minSdkVersion 7
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

sourceSets {
    unitTest {
        java.srcDir file('src/test/java')
        resources.srcDir file('src/test/res')
    }
}

configurations {
    unitTestCompile.extendsFrom runtime
    unitTestRuntime.extendsFrom unitTestCompile
}

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

    unitTestCompile files("$project.buildDir/classes/release")
    unitTestCompile 'junit:junit:4.+'
    unitTestCompile 'org.robolectric:robolectric:2.+'
    unitTestCompile 'com.google.android:android:4.+'
    unitTestCompile project (':lib')
    unitTestCompile fileTree(dir: 'libs', include: ['*.jar', '*.aar'])

    instrumentTestCompile 'junit:junit:4.+'
    instrumentTestCompile 'org.robolectric:robolectric:2.+'
}

task unitTest(type:Test, dependsOn: assemble) {
    testClassesDir = project.sourceSets.unitTest.output.classesDir
    classpath = project.sourceSets.unitTest.runtimeClasspath
}
check.dependsOn unitTest

And finally the source of the three java-classes, starting with DummyData:

package de.ivu.junittest;

import android.util.Log;

public class DummyData {
    private int data;

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }
}

The DummyModel class:

package de.ivu.junittest.app;

import android.util.Log;

import de.ivu.junittest.DummyData;

public class DummyModel {    
    private DummyData data = new DummyData();

    public void setData(int data) {
        this.data.setData(data);
    }

    public int getData() {
        return this.data.getData();
    }
}

And finally, DummyModelTest:

import static org.junit.Assert.assertEquals;
import org.junit.runner.RunWith;
import org.junit.Test;

import org.robolectric.RobolectricTestRunner;

import de.ivu.junittest.app.DummyModel;

@RunWith(RobolectricTestRunner.class)
public class DummyModelTest {
    @Test
    public void testInstantiation() {
        DummyModel model = new DummyModel();
        model.setData(42);
        assertEquals(model.getData(), 42);
    }
}

After trying more than a dozen different things, any help is deeply appreciated.


回答1:


The trick is to add the other modules' classes directories as dependency. So you end up with unitTestCompile files instead of unitTestCompile project:

dependencies {
    ...
    unitTestCompile files("../lib/classes/release")
    ...
}

Not very beautiful, nor very intuitive, but it works with my current setup (Gradle 1.10, Build Tools 19.0.1, and Android-Gradle-plugin 0.8).



来源:https://stackoverflow.com/questions/21673395/how-to-run-unit-tests-with-dependency-to-an-android-library-module

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!