简体   繁体   English

Robolectric 单元测试因 Android Studio 2.3 更新而失败

[英]Robolectric Unit Test failing with Android Studio 2.3 updates

All my Unit Test started throwing this error:我所有的单元测试都开始抛出这个错误:

No such manifest file: build\intermediates\bundles\debug\AndroidManifest.xml

java.lang.NullPointerException
    at org.robolectric.shadows.ShadowAssetManager.getAndResolve(ShadowAssetManager.java:375)
    at org.robolectric.shadows.ShadowAssetManager.getResourceValue(ShadowAssetManager.java:117)
    at android.content.res.AssetManager.getResourceValue(AssetManager.java)
    at android.content.res.Resources.getValue(Resources.java:1347)
    at android.support.v7.widget.AppCompatDrawableManager.loadDrawableFromDelegates(AppCompatDrawableManager.java:332)
    at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:197)
    at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:190)
    at android.support.v7.widget.AppCompatDrawableManager.checkVectorDrawableSetup(AppCompatDrawableManager.java:711)
    at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:195)
    at android.support.v7.widget.TintTypedArray.getDrawableIfKnown(TintTypedArray.java:81)
    at android.support.v7.app.AppCompatDelegateImplBase.__constructor__(AppCompatDelegateImplBase.java:131)
    at android.support.v7.app.AppCompatDelegateImplBase.<init>(AppCompatDelegateImplBase.java)
    at android.support.v7.app.AppCompatDelegateImplV9.<init>(AppCompatDelegateImplV9.java)
    at android.support.v7.app.AppCompatDelegateImplV11.<init>(AppCompatDelegateImplV11.java)
    at android.support.v7.app.AppCompatDelegateImplV14.<init>(AppCompatDelegateImplV14.java)
    at android.support.v7.app.AppCompatDelegateImplV23.<init>(AppCompatDelegateImplV23.java)
    at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:203)
    at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:185)
    at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:519)
    at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:71)
    at android.app.Activity.performCreate(Activity.java:6237)
    at org.robolectric.util.ReflectionHelpers.callInstanceMethod(ReflectionHelpers.java:195)
    at org.robolectric.util.ActivityController$1.run(ActivityController.java:126)
    at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:340)
    at org.robolectric.shadows.CoreShadowsAdapter$2.runPaused(CoreShadowsAdapter.java:40)
    at org.robolectric.util.ActivityController.create(ActivityController.java:123)
    at org.robolectric.util.ActivityController.create(ActivityController.java:133)
    at com.si.play.adapter.RosterAdapter2Test.setUp(RosterAdapter2Test.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:250)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:176)
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:142)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)

It worked just fine.它工作得很好。 The only thing that I changed is that I updated Android Studio to 2.3 and the gradle plugin to 2.3.我唯一改变的是我将 Android Studio 更新到 2.3 并将 gradle 插件更新到 2.3。 So far I fix it by manually writing down $MODULE_DIR$ in each test's Run Configuration path.到目前为止,我通过在每个测试的运行配置路径中手动写下$MODULE_DIR$来修复它。 But is really annoying write it down every time.但是真的很烦,每次都写下来。 Has anyone experience something like this?有没有人经历过这样的事情?

Set it by default, so every new test configuration that you create will inherit it: 默认设置它,因此您创建的每个新测试配置都将继承它:

默认设置

Run > Edit Configurations... > Defaults > Android JUnit 运行 > 编辑配置... > 默认值 > Android JUnit

in Working directory enter: $MODULE_DIR$ 工作目录中输入: $MODULE_DIR$

Android studio is looking at APP folder to run tests from AS 2.3 version. Android工作室正在查看APP文件夹以运行AS 2.3版本的测试。 If you have Custom Roboelectric Runner extending RoboelectricTestRunner, you can override the working directory inside that, instead of setting WORKING DIR from edit configurations every time. 如果您有自定义Roboelectric Runner扩展RoboelectricTestRunner,您可以覆盖其中的工作目录,而不是每次都从编辑配置设置WORKING DIR。

Here is my code. 这是我的代码。

`public class CustomRobolectricRunner extends RobolectricTestRunner { `public class CustomRobolectricRunner扩展了RobolectricTestRunner {

// Build output location for Android Studio 2.2 and older
private static final String BUILD_OUTPUT = "build/intermediates";

// Build output location for Android Studio 2.3 and newer
private static final String BUILD_OUTPUT_APP_LEVEL = "app/build/intermediates";

public CustomRobolectricRunner(Class<?> testClass) throws InitializationError {
    super(testClass);
}

@Override
protected AndroidManifest getAppManifest(Config config) {
    FileFsFile res = FileFsFile.from(BUILD_OUTPUT, "/res/merged", BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE);
    FileFsFile assets = FileFsFile.from(BUILD_OUTPUT, "assets", BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE);
    FileFsFile manifest = FileFsFile.from(BUILD_OUTPUT, "manifests", "full", BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE, "AndroidManifest.xml");

    // If above files does not exist in the specified paths, look them at the app folder level. This is needed
    // as Android studio 2.3 changed the working directory.
    if (!manifest.exists()) {
        manifest = FileFsFile.from(BUILD_OUTPUT_APP_LEVEL, "manifests", "full", BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE, "AndroidManifest.xml");
    }

    if (!res.exists()) {
        res = FileFsFile.from(BUILD_OUTPUT_APP_LEVEL, "/res/merged", BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE);
    }

    if (!assets.exists()) {
        assets = FileFsFile.from(BUILD_OUTPUT_APP_LEVEL, "assets", BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE);
    }

    AndroidManifest androidManifest = new AndroidManifest(manifest, res, assets) {
        @Override
        public Class getRClass() {
            return R.class;
        }

        public int getTargetSdkVersion() {
            /**
             * Lollipop is currently the highest version supported in 3.0.
             */
            return Build.VERSION_CODES.LOLLIPOP;
        }
    };

    return androidManifest;
}`

When someone is facing this issue,for this case, adding this line should help当有人遇到此问题时,对于这种情况,添加此行应该会有所帮助

in "android" brackets在“android”括号中

in app/build.gradle在 app/build.gradle

testOptions.unitTests {
includeAndroidResources = true

} }

Bye bye再见

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM