在使用Robolectric时,调用recreate(注意,使用Robolectric时无需担心旧API版本)相当于模拟配置更改,但不一定会捕获您可能发生的所有错误。特别是它不会创建Activity的新实例(我很确定它也不会“清除”它),因此,如果您忘记还原Activity的成员字段,您的测试将无法捕获该错误。但对于测试片段而言,它的效果足够好(非保留片段会被销毁并重新实例化)。
如果在Robolectric测试中调用Activity的recreate,则会发生以下内容:
- onSaveInstanceState
- onPause
- onStop
- onDestroy
- onCreate
- onStart
- onRestoreInstanceState
- onResume
(我通过在测试Activity中覆盖大多数生命周期方法并在其中放置记录语句来发现这一点)
您可以使用以下代码更接近真实的配置更改:
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或更高版本,则在.resume()
之后可能需要调用.visible()
。)
使用上述代码,您会看到以下事件发生:
- onSaveInstanceState
- onPause
- onStop
- onDestroy
- 实例化 Activity 的新实例(以下所有调用均在此新实例上执行)
- onCreate
- onStart
- onRestoreInstanceState
- onResume
- onPostResume
虽然仍不完全匹配,但与遇到真正的配置更改时会发生的情况更接近了。
我认为这可能是当由于低内存而销毁活动时会发生的情况的不错模拟,因为与调用recreate()不同,我认为它不会保留对已保留片段的引用。但在这个领域我还很薄弱!
更新:
如果您的 Activity 是通过intent启动的,您可能需要添加一个withIntent调用,像这样:
Robolectric.buildActivity(YourActivity.class).withIntent(intent).create(bundle) // and so on...