在我看来,使用 Robolectric 的生命周期实用程序(从 Robolectric.buildActivity()
开始)构建活动单元测试并使用 Mockito 间谍监视同一活动是相互排斥的。
由于 buildActivity()
控制 Activity 对象的构造,因此唯一为活动添加间谍的位置是在调用 buildActivity()
之后。但是,间谍在事后添加时无法正常运行。
在监视ActivityController
生命周期方法(如create()
、start()
和resume()
)的副作用时尤其如此。我认为这是因为活动控制器包含对"真实"活动对象的引用,而不是后来添加的间谍。
那么有没有办法监视正在使用 Robolectric 进行单元测试的活动,以便间谍在通过 Robolectric 的ActivityController
调用生命周期方法时正常工作?
答案是使用反射替换ActivityController
中的"真实"Activity
对象。
@Test
public void someTestMethod() throws NoSuchFieldException, IllegalAccessException {
ActivityController<LoginActivity> ac = Robolectric.buildActivity(LoginActivity.class);
LoginActivity spiedActivity = spy(ac.get());
replaceComponentInActivityController(ac, spiedActivity);
ac.create();
// do your work
}
public static void replaceComponentInActivityController(ActivityController<?> activityController, Activity activity)
throws NoSuchFieldException, IllegalAccessException {
Field componentField = ComponentController.class.getDeclaredField("component");
componentField.setAccessible(true);
componentField.set(activityController, activity);
}
我通过 Robolectric
3.1 对其进行了测试,没关系。
至少对于活动不是被测对象,而只是托管被测片段的虚拟活动的情况,可以在测试活动中注入一个模拟,该模拟可以通过片段和活动之间的通信接口验证与活动的交互(如下 http://developer.android.com/training/basics/fragments/communicating.html)。