在 Robolectric 中调用 recreate(请注意,使用 Robolectric 时不必担心旧的 API 版本)非常接近于模拟配置更改,但不一定会捕获您可能犯的所有错误。特别是它不会创建 Activity 的新实例(而且我很确定它不会“擦洗”它),因此如果您忘记恢复 Activity 的成员字段,您的测试将无法捕捉到这一点。不过,它确实可以很好地测试片段(未保留的片段被销毁并重新实例化)。
如果您在 Robolectric 测试中对 Activity 调用 recreate,则会发生以下情况:
- onSaveInstanceState
- 暂停
- 停止
- 销毁
- 创建
- 开始
- onRestoreInstanceState
- 恢复
(我通过在测试活动中覆盖大多数生命周期方法并将日志语句放入其中发现了这一点)
您可以使用如下代码更接近真实的配置更改:
Bundle bundle = new Bundle();
activityController.saveInstanceState(bundle).pause().stop().destroy();
controller = Robolectric.buildActivity(YourActivity.class).create(bundle).start().restoreInstanceState(bundle).resume();
activity = controller.get();
(此代码适用于 Robolectric 2.1 - 如果您使用的是 2.2 或更高版本,您可能需要.visible()
在那之后打电话.resume()
)
使用上述内容,您将看到以下事件发生:
- onSaveInstanceState
- 暂停
- 停止
- 销毁
- 实例化 Activity 的新实例(所有后续调用都在这个新实例上)
- 创建
- 开始
- onRestoreInstanceState
- 恢复
- onPostResume
这仍然不是完全匹配,但更接近于遇到真正的配置更改时会发生的情况。
我认为这可能是对由于内存不足而破坏活动时发生的情况的一个不错的模拟,因为与调用 recreate() 不同,我认为这不会保留对保留片段的引用。不过,我在这个地区的处境很不稳定!
更新:
如果您的 Activity 是通过 Intent 启动的,您可能需要添加对 withIntent 的调用,如下所示:
Robolectric.buildActivity(YourActivity.class).withIntent(intent).create(bundle) // and so on...