2

这不完全是一个问题,因为我找到了问题的解决方案。只是希望它能帮助其他遇到它的人。

我们使用 Robolectric 为使用库(实际上是几个库)的项目编写单元测试。库和应用程序使用大量资源。

让我们假设 Eclipse 工作区包含项目库(以“library.package”作为顶级包)创建一个 Android 库和项目应用程序(顶部为“app.package”),它使用库。项目Test是Robolectric项目,指的是Application项目。

突然间,我们发现检查活动中是否存在特定视图的非常简单的测试失败了。例如:

@Test
public void testProgressBarInit() {
    LoginActivity activity = Robolectric.buildActivity(LoginActivity.class).create().get();

   assertTrue(activity.findViewById(R.id.status_text) instanceof TextView);

}

库项目实现了 LoginActivity 并定义了适当的资源(布局)。在我们稍微改变代码结构消除一个库之前,失败的测试可以完美运行。

在调试器下运行测试表明 findViewById 调用使​​用了从 Application/gen/R.java 文件中获取的 R.id.status_text 的正确值。同时我们发现Application/gen/R.java中R.id.status文本的值与Library/gen/R.java中的值不同。此外,Appication/gen 目录包含文件 library.package.R.java,其中包含与 Application/gen/R.java 中相同的 status_text 值(与 Library/gen/R.java 中的原始值不同)。这是 aapt 工具的正常行为,它可以在合并来自库和应用程序的资源时更改资源 ID。

4

1 回答 1

3

经过一番调查,我们发现了以下几点:

  1. Robolectric 两次加载在库中定义的资源 ID:一次使用应用程序项目中的 R.class,另一次使用库项目中的 R.class

  2. 加载哪个类取决于类路径配置

  3. 要运行测试,我们需要从应用程序项目中导出库项目

  4. 如果在类路径配置中的 Application/gen 文件夹之前导出库项目,Robolectric 将资源 ID 替换为在 Library/bin/classes/library/package/R.class 中找到的资源 ID

  5. 如果在 Application/gen 文件夹之后导出库项目,Robolectric 将使用在 Application/bin/library/package/R.class 中找到的正确资源。

这肯定是 Robolectric 实现中的一个错误,因为它不应该从与库包关联的 R.class 加载资源 ID。所有 id 都传播到 Application/gen/R.java(参见GitHub 上的讨论)。

如果您在使用 Robolectric 时遇到资源使用问题或类似问题,请确保在 Build Path-Order 和 Export 配置中的 Application/gen 文件夹之后导出库项目。

于 2013-06-14T17:37:50.130 回答