Robolectric:“未找到 AndroidManifest.xml”和“无法找到资源 ID #0x7f09001b”

问题描述 投票:0回答:3

我正在使用 Roboletric 运行一些测试,但遇到了一个无法解决的问题。 当我运行测试时,“AndroidManifest”出现以下错误:

警告:在 .\AndroidManifest.xml 中找不到清单文件。

仅退回到 Android 操作系统资源。要删除此警告,请注释 使用 @Config(manifest=Config.NONE) 的测试类。

没有这样的清单文件:.\AndroidManifest.xml

我尝试过这些解决方案,但失败了

@Config (manifest = Config.DEFAULT_MANIFEST_NAME) @Config(manifest = Config.NONE, constants = BuildConfig.class, sdk = 26) @Config( constants = BuildConfig.class, manifest="src/main/AndroidManifest.xml", sdk = 26 )

执行过程中的另一个错误是:

android.content.res.Resources$NotFoundException:无法找到 包中的资源 ID #0x7f09001b [android, org.robolectric.default]

...

com.example.robertoassad.alltestsmerge.MainActivity.onCreate(MainActivity.java:52)

有错误的这一行是以下代码:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

具体在:setContentView(R.layout.activity_main);



对我来说,我认为这个问题没有意义......

详情:

  • 测试类位于文件夹:

    app\src\test\java\com\example\robertoassad

  • 测试是:

    @RunWith( RobolectricTestRunner.class) public class Roboletric {

    
         @Test
         public void clickingLogin_shouldStartLoginActivity() {
             MainActivity activity = Robolectric.setupActivity(MainActivity.class);
             activity.findViewById(R.id.button2).performClick();
    
    
    

    Intent expectedIntent = new Intent(activity, SecondActivity.class); Intent actual = ShadowApplication.getInstance().getNextStartedActivity(); assertEquals(expectedIntent.getComponent(), actual.getComponent()); }
    
    

    }

android compiler-errors android-manifest robolectric
3个回答
12
投票
我遇到了与你面临的类似的问题。 jongerrish

在 Robolectric GitHub Issue 上关于此问题的帖子解决了我的问题。

对我有用的答案的方面是在我的模块的

testOptions

 文件中添加一个 
build.gradle
 块:

testOptions { unitTests { includeAndroidResources = true } }

添加此块后,我的测试能够运行并访问字符串资源。


2
投票
这个问题困扰了我一段时间,这是我在测试代码中的注释。

关于舱单位置

使用 Gradle 构建系统,Robolectric 按以下顺序查找 AndroidManifest.xml。

  • Java资源文件夹

  • 构建/中间体/清单/[完整或快速启动]/[构建类型]

因此,根据源代码文件夹组织(例如 src/main/AndroidManifest.xml)指定 AndroidManifest.xml 的位置是一个常见的错误。指定的 AndroidManifest.xml 位置也会影响 Robolectric 查找合并资源的方式。因此,如果测试中找不到某些资源,可能是由于 AndroidManifest.xml 位置设置不正确。

也就是说,Android Gradle 插件会合并 AndroidManifest.xml 并将结果放在上述中间目录下。所以src/main/AndroidManifest.xml的内容会影响测试结果。

因此,如果您想在 @Config 中指定清单选项,只需使用 @Config(manifest=“AndroidManifest.xml”) 应该就可以了。如果你想使用备用的AndroidManifest.xml,请将其放在Java资源文件夹中,并根据资源文件夹中的相对路径指定@Config。


0
投票
我在从应用程序测试我的库模块时也遇到了同样的问题。现在我的接收器和服务位于我的库中,因此为了测试它们,我必须实现自定义测试类,以便 Roboelectric 可以指向我的库清单而不是应用程序清单:

import android.os.Build; import org.junit.runners.model.InitializationError; import org.robolectric.manifest.AndroidManifest; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import org.robolectric.res.Fs; import java.io.File; import java.io.IOException; public class RobolectricGradleTestRunner extends RobolectricTestRunner { private static final String PROJECT_DIR = "C:/MyProject/"; private static final int MAX_SDK_SUPPORTED_BY_ROBOLECTRIC = Build.VERSION_CODES.JELLY_BEAN_MR2; public RobolectricGradleTestRunner(final Class<?> testClass) throws Exception { super(testClass); } private static AndroidManifest getAndroidManifest() { String manifestPath = PROJECT_DIR+"/src/main/AndroidManifest.xml"; String resPath = PROJECT_DIR+"/src/main/res"; String assetPath = PROJECT_DIR+"/src/main/assets"; System.out.print("manifest path: "+manifestPath); System.out.print("resPath path: "+resPath); System.out.print("assetPath path: "+assetPath); return new AndroidManifest( Fs.fileFromPath(manifestPath), Fs.fileFromPath(resPath), Fs.fileFromPath(assetPath)) { @Override public int getTargetSdkVersion() { return MAX_SDK_SUPPORTED_BY_ROBOLECTRIC; } }; } private static String getProjectDirectory() { String path = ""; try { File file = new File(".."); path = file.getCanonicalPath(); path = path + "/app/"; } catch (IOException ex) {} return path; } @Override public AndroidManifest getAppManifest(Config config) { return getAndroidManifest(); } }

并在您的测试类中使用它,例如:

@RunWith(RobolectricGradleTestRunner.class) public class MyClassChangeTest { }
    
© www.soinside.com 2019 - 2024. All rights reserved.