我有一个使用 activityTestRule
的简单测试这应该检查是否调用了被测 Activity 的方法:
@Test
public void callLiveLocation() {
MapSettingsActivity spy = spy(activityRule.getActivity());
doNothing().when(spy).setLiveLocation();
onView(withId(R.id.btn_map_current_location)).perform(click());
verify(spy).setLiveLocation();
}
方法
setLiveLocation()
当我在 Debug模式下检查时被调用。但是,控制台告诉我:
Wanted but not invoked: mapSettingsActivity.setLiveLocation(); -> at com.android.dx.mockito.InvocationHandlerAdapter.invoke(InvocationHandlerAdapter.java:53) Actually, there were zero interactions with this mock.
如何检查是否调用了被测 Activity 的方法?
我对按钮单击使用 Android 的数据绑定(bind),它会调用回调,而回调又会调用被测 Activity 的方法。
笔记:
该方法是 Activity 上的一个简单方法:
public void setLiveLocation() {
super.startLocationListener();
}
编辑:
我注意到创建 spy 返回 null 的原因尚不清楚:
MapSettingsActivity spy = spy(activityRule.getActivity());
最佳答案
首先,这不是您问题的确切解决方案,但也许它会对您有所帮助。
所以这就是我处理类似问题的方式。一般来说:为了让 Mockito 能够检测到对 spy 对象的方法调用,必须在 spy 对象上调用这个方法(如果你明白我在说什么,因为我不明白))。在你的情况下这不是真的。您的 setLiveLocation 调用了存储在 ActivityTestRule 中的真实 Activity 实例。
我的例子:
我需要验证 RecyclerView 的适配器 updateDataSet() 方法是否只调用了一次。这就是我在 Kotlin 中的做法:
val adapter = activityTestRule.activity
.find<RecyclerView>(R.id.reviewsList)
.adapter as FlexibleAdapter<ReviewItem>
assertNotNull(adapter)
val spy = spy(adapter)
activityTestRule.activity
.runOnUiThread {
activityTestRule.activity
.find<RecyclerView>(R.id.reviewsList)
.adapter = spy
}
doNothing().`when`(spy).updateDataSet(ArgumentMatchers.any())
onView(withId(R.id.swipeRefresh)).perform(ViewActions.swipeDown())
verify(spy, times(1)).updateDataSet(MOCKED_REVIEWS_FROM_SERVER.map(::ReviewItem))
所以基本上我从 Recycler 获得适配器并将其更改为我的 spy 适配器。仅当我进行此替换时,我的测试才成功完成。
在您的情况下 ActivityTestRule 包含真实 Activity 的实例,因此您需要以某种方式将其替换为 spy 对象。我不知道该怎么做,但我想有机会创建这个规则的子类,并可能在构造函数中创建 Activity spy 。然后您将获得 spy 对象并使用它来验证任何调用。
关于android - Espresso/Mockito 验证该方法是否被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47081174/