I recently updated a few libraries in my gradle file, and as a result, some (but not all) of my unit tests fail when I run them in the console by "./gradlew clean test". However, all my tests pass successfully when I run them inside Android Studio.
Here is a snapshot of my gradle file:
apply plugin: 'com.android.application'
apply plugin: 'android-aspectj'
apply plugin: 'android'
apply plugin: 'idea'
apply plugin: 'org.robolectric'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
minSdkVersion 17
targetSdkVersion 19
}
signingConfigs {
release {
...
}
}
sourceSets {
main {
manifest.srcFile 'src/main/AndroidManifest.xml'
java.srcDirs = ['src/main/java']
res.srcDirs = ['src/main/res']
assets.srcDirs = ['src/main/assets']
}
test.setRoot("src/test")
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
signingConfig signingConfigs.release
}
debug {
...
}
}
lintOptions {
abortOnError false
}
testOptions {
unitTests.returnDefaultValues = true
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES.txt'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/notice.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/dependencies.txt'
exclude 'META-INF/LGPL2.1'
}
}
buildscript {
repositories {
mavenCentral()
mavenLocal()
jcenter()
maven {
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
}
dependencies {
classpath 'com.github.dcendents:android-maven-plugin:1.0'
classpath 'com.uphyca.gradle:gradle-android-aspectj-plugin:0.9.+'
classpath 'org.robolectric:robolectric-gradle-plugin:1.0.1'
}
}
dependencies {
compile 'com.android.support:support-v4:22.1.1'
compile 'com.android.support:appcompat-v7:22.1.1'
compile 'com.google.android.gms:play-services:7.3.0'
compile 'org.apache.httpcomponents:httpcore:4.3'
compile 'org.apache.httpcomponents:httpmime:4.3.5'
compile 'org.apache.httpcomponents:httpclient:4.3.5'
compile 'com.google.code.gson:gson:2.3'
testCompile 'org.hamcrest:hamcrest-integration:1.3'
testCompile 'org.hamcrest:hamcrest-core:1.3'
testCompile 'org.hamcrest:hamcrest-library:1.3'
testCompile 'com.squareup:fest-android:1.0.+'
testCompile 'org.mockito:mockito-core:1.+'
testCompile 'org.jmockit:jmockit:1.8'
testCompile('junit:junit:4.12') {
exclude module: 'hamcrest-core'
}
testCompile('org.robolectric:robolectric:2.4') {
exclude module: 'classworlds'
exclude module: 'commons-logging'
exclude module: 'httpclient'
exclude module: 'maven-artifact'
exclude module: 'maven-artifact-manager'
exclude module: 'maven-error-diagnostics'
exclude module: 'maven-model'
exclude module: 'maven-project'
exclude module: 'maven-settings'
exclude module: 'nekohtml'
exclude module: 'plexus-container-default'
exclude module: 'plexus-interpolation'
exclude module: 'plexus-utils'
exclude module: 'wagon-file'
exclude module: 'wagon-http-lightweight'
exclude module: 'wagon-http-shared'
exclude module: 'wagon-provider-api'
}
}
idea {
module {
testOutputDir = file("build/test-classes")
testSourceDirs += file('test/')
}
}
The error I am getting is this:
java.lang.NullPointerException
at mockit.internal.mockups.MockStates.getMockState(MockStates.java:99)
at mockit.internal.mockups.MockStates.updateMockState(MockStates.java:92)
at mockit.internal.state.TestRun.updateMockState(TestRun.java:138)
at org.junit.runners.model.FrameworkMethod.validatePublicVoidNoArg(FrameworkMethod.java)
at org.junit.runners.ParentRunner.validatePublicVoidNoArgMethods(ParentRunner.java:155)
at org.junit.runners.BlockJUnit4ClassRunner.validateTestMethods(BlockJUnit4ClassRunner.java:208)
at org.junit.runners.BlockJUnit4ClassRunner.validateInstanceMethods(BlockJUnit4ClassRunner.java:188)
at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:128)
at org.junit.runners.ParentRunner.validate(ParentRunner.java:416)
My custom RobolectricGradleTestRunner is:
public class RobolectricGradleTestRunner extends RobolectricTestRunner {
private static final int MAX_SDK_SUPPORTED_BY_ROBOLECTRIC = 18;
public RobolectricGradleTestRunner(Class<?> testClass) throws InitializationError {
super(testClass);
}
@Override
protected AndroidManifest getAppManifest(Config config) {
String dir = System.getProperty("user.dir");
String manifestProperty = dir + "/build/intermediates/manifests/full/debug/AndroidManifest.xml";
String resProperty = dir + "/build/intermediates/res/debug";
return new AndroidManifest(Fs.fileFromPath(manifestProperty), Fs.fileFromPath(resProperty)) {
@Override
public int getTargetSdkVersion() {
return MAX_SDK_SUPPORTED_BY_ROBOLECTRIC;
}
};
}
}
And this is one of my tests that is failing:
@RunWith(RobolectricGradleTestRunner.class)
public class AboutActivityTest {
private AboutActivity activity;
@Before
public void initialize() {
activity = Robolectric.buildActivity(AboutActivity.class).create().start().get();
}
@Test
public void testAboutPage() {
assertNotNull("AboutActivity is null", activity);
Fragment fragment = activity.getFragmentManager().findFragmentByTag(AboutFragment.FRAGMENT_TAG);
assertNotNull("fragment is null", fragment);
Button button = (Button) fragment.getView().findViewById(R.id.buttonTour);
assertNotNull("Tour button is null", button);
ShadowActivity shadowHome = Robolectric.shadowOf(activity);
button.performClick();
assertThat(shadowHome.peekNextStartedActivityForResult().intent.getComponent(), equalTo(new ComponentName(activity, TourActivity.class)));
}
}
Based on what I see, it seems jmockit is having some problem to initialize. But I am not sure what it is. Any help is greatly appreciated.