1

我有一个使用这么多库的 Android 应用程序,我现在需要使用 MultiDex-ing。不幸的是,当我引入多索引时,我现有的 Robolectric 单元测试不再运行甚至启动。在我添加多 dexing 之前,它们运行得非常好。

参考github上的原bug帖子

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

并提出解决方案

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

我仍然无法让我的单元测试运行。

以下是我的 build.gradle 文件版本 1 的片段,我在其中尝试获取最新的 robolectric 快照以及可以在我的代码中使用的 ShadowMultiDex.java。

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'
    }

我还创建了一个包含内容的 org.robolectric.Config.properties 文件

shadows=org.robolectric.shadows.ShadowMultiDex

有了以上内容,我开始进入我的测试类,并将 ShadowMultiDex 包含在我的小测试中。

@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();
    }
}

当我运行单元测试时,我仍然会得到一个 NullPointerException 来设置应用程序及其元数据。我正在寻找的是看看其他人做了什么来真正解决这个问题并让它运行。

4

1 回答 1

0

您是否尝试过使用Android 单元测试支持+ Multidex + Robolectric + Mockito ?

我让它进行了一些小改动:

  • 我无法通过 AS 运行单元测试,只能通过命令行运行。
  • 需要使用 1.9.0 版的 Mockito,因为 1.9.5 版不能与 Robolectric + Multidex 一起正常工作。(如果你让它工作,请分享:))。我在仪器测试中使用的是 1.9.5 版本。
  • 在我的 MainApplication 上实现了 attachBaseContext,如下所示:
  @Override
  protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    try{
        MultiDex.install(this);
    } catch (RuntimeException ignore){
        //Multidex error when running Robolectric tests => ignore.
    }
  } 
  • 必须排除重复的依赖项(查看这篇文章

  • 我正在使用自定义 Robolectric 跑步者,我刚刚实现了它的构造函数(设置资源文件的正确路径):

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);
}

希望能帮助到你。

于 2015-03-24T15:20:10.760 回答