1

I have an Android app that uses so many libraries that I now need to use MultiDex-ing. Unfortunately, when I introduced multidexing, my existing Robolectric unit tests no longer run or even startup. They ran perfectly fine before I added in multi dexing.

Referring to the original bug post on github

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

and proposed solution

https://github.com/robolectric/robolectric/pull/1457

I have still not been able to get my unit test to run.

The following is a snippet of my build.gradle file version 1 where I am trying to get the latest robolectric snap shot and also the ShadowMultiDex.java that I could use in my code.

buildscript {
    repositories {
        mavenCentral()
        maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
    }
    dependencies {
        classpath 'org.robolectric:robolectric-gradle-plugin:0.14.+'
    }
}

repositories {
    maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
}

apply plugin: 'android'
apply plugin: 'robolectric'
apply plugin: 'com.android.application'

...

android {
    // other things
    ...

    sourceSets {
        androidTest {
            setRoot('src/test')
            resources.srcDirs = ['assets']
        }
    }
}

dependencies {
    // regular
    ...

    // unit testing
    androidTestCompile fileTree(dir: 'libs/test', include: '*.jar')
    androidTestCompile('com.squareup:fest-android:1.0.+') {
        exclude group: 'com.android.support'
    }
    androidTestCompile 'com.google.dexmaker:dexmaker:1.+'


    androidTestCompile('junit:junit:4.11') {
        exclude module: 'hamcrest-core'
    }
    androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
    androidTestCompile 'org.mockito:mockito-core:1.9.5'
    androidTestCompile 'org.robolectric:android-all:+'
    androidTestCompile 'org.robolectric:shadows-multidex:3.0-SNAPSHOT'
    androidTestCompile('org.robolectric:robolectric:3.0-SNAPSHOT') {
        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: 'plexus-container-default'
        exclude module: 'plexus-interpolation'
        exclude module: 'plexus-utils'
        exclude module: 'wagon-file'
        exclude module: 'wagon-http-lightweight'
        exclude module: 'wagon-provider-api'
    }

I also created a org.robolectric.Config.properties file with the contents

shadows=org.robolectric.shadows.ShadowMultiDex

With the above, I proceeded to go into my test class and include the ShadowMultiDex in my small test.

@RunWith(RobolectricGradleTestRunner.class)
@Config(shadows = {ShadowMultiDex.class})
public class AppVersionTest extends MyBaseTest {

    @Before
    @Override
    public void setUp() throws Exception {
        super.setUp();
    }

    @Test
    public void testIsDefaultTrue() {
        // setup
        AppVersion appVersion = new AppVersion(null);

        // run
        boolean result = appVersion.isDefault();

        // verify
        assertThat(result).isTrue();
    }
}

When I ran through the unit tests, I would still get a NullPointerException for setting up the Application and its metadata. What I am looking for is to see what others have done to actually fix this problem and to get it to run.

jww
  • 97,681
  • 90
  • 411
  • 885
lazypig
  • 747
  • 1
  • 6
  • 22

1 Answers1

0

Have you tried using Android Unit Testing Support + Multidex + Robolectric + Mockito ?.

I have it working with some small changes:

  • I can't run the Unit tests through AS, only command line.
  • Need to use version 1.9.0 of Mockito as version 1.9.5 is not working propertly with Robolectric + Multidex. (if you make it work, please share :) ). I'm using version 1.9.5 in my instrumentation tests.
  • Implemented the attachBaseContext on my MainApplication as follows:
  @Override
  protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    try{
        MultiDex.install(this);
    } catch (RuntimeException ignore){
        //Multidex error when running Robolectric tests => ignore.
    }
  } 
  • Must exclude duplicate dependencies (check this post)

  • I'm using a custom Robolectric runner, where I've just implemented its constructor (to set the correct path of resource files):

public RobolectricCustomRunner(Class<?> testClass) throws InitializationError     {
    super(testClass);
    String buildVariant = (BuildConfig.FLAVOR.isEmpty() ? "" : BuildConfig.FLAVOR+ "/") + BuildConfig.BUILD_TYPE;
    String intermediatesPath = "build/intermediates";

    System.setProperty("android.package", BuildConfig.APPLICATION_ID);
    System.setProperty("android.manifest", intermediatesPath + "/manifests/full/" + buildVariant + "/AndroidManifest.xml");
    System.setProperty("android.resources", intermediatesPath + "/res/" + buildVariant);
    System.setProperty("android.assets", intermediatesPath + "/assets/" + buildVariant);
}

Hope it helps.

Community
  • 1
  • 1
marbarfa
  • 677
  • 1
  • 7
  • 16