在膨胀视图时,Robolectric使用来自库的不正确的资源ID

时间:2013-06-11 02:07:36

标签: resources robolectric

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

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

让我们假设Eclipse工作区包含项目库(“library.package”作为顶层包),它创建了一个Android库和项目应用程序(顶部带有“app.package”),它使用了库。项目测试是Robolectric项目,它涉及应用项目。

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

@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。

1 个答案:

答案 0 :(得分:3)

经过一些调查,我们发现了以下内容:

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

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

  3. 运行测试我们需要从Application项目中导出Library项目

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

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

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

    如果在使用Robolectric时遇到资源使用问题或类似问题,请确保在构建路径 - 订单和导出配置中的Application / gen文件夹之后导出库项目。