我对android很陌生,试图了解bundle是如何工作的。

我被以下单元测试所阻止。有人可以解释为什么会失败吗?

@Test
public void testBundle() throws Exception {
    Bundle bundle = new Bundle();
    String key = "hello";
    String value = "world";
    bundle.putString(key, value);
    Assert.assertEquals(value, bundle.getString(key));
}

junit.framework.ComparisonFailure:
Expected :world
Actual   :null

最佳答案

JUnit 测试在本地机器上运行,该机器没有所有的 Android 源代码,只有 stub 类(描述 here )。这些 stub 类允许您针对它们编译 Android 应用程序(因为它们的 API 与实际的 Android 框架相同),但它们不包含任何逻辑以使它们“轻巧”。

默认情况下,如果您尝试调用任何 stub 方法,则会出现异常。像这样的东西:

public Bundle() {
    throw new RuntimeException("Stub!");
}

采用这种“快速失败”的方法是为了防止开发人员意外地针对这些 stub 类运行他们的代码,然后想知道为什么它不起作用。

但是,可以使用 build.gradle 中的此配置更改此行为:
android {
  ...
  testOptions {
    unitTests.returnDefaultValues = true
  }
}

这使得 stub 方法返回默认值而不是抛出异常。

您可能启用了此功能,因此在运行 JUnit 测试时不会出现异常,但 Bundle#getString() 方法仅返回默认值(即 null )。

如果要测试具有 Android 框架依赖项的代码,您应该执行以下任一操作:
  • 模拟这些依赖(例如 Mockito)
  • 使用 Robolectric 运行测试
  • 在 Android 设备上运行仪器测试

  • 在任何情况下,unitTests.returnDefaultValues = true 都是一个非常危险的功能,因为它使您的测试不可靠:某些测试可以通过,因为 stub 方法返回了默认值,但该功能在真实设备上将失败。把它关掉。

    10-07 19:37
    查看更多