Espresso / Mockito 验证该方法被调用

Tra*_*ace 6 android mockito android-espresso

我有一个简单的测试,activityTestRule它应该检查被测活动的方法是否被调用:

@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();
}
Run Code Online (Sandbox Code Playgroud)

setLiveLocation()当我在调试模式下检查时正在调用该方法。
然而,控制台告诉我:

想要但未调用:mapSettingsActivity.setLiveLocation(); -> at com.android.dx.mockito.InvocalHandlerAdapter.invoke(InvocalHandlerAdapter.java:53) 实际上,与此模拟的交互为零。

如何检查被测活动的方法是否被调用?
我使用 Android 的数据绑定来单击按钮,这会调用回调,而回调又会调用被测活动的方法。

笔记:

该方法是一个关于activity的简单方法:

public void setLiveLocation() {
    super.startLocationListener();
}
Run Code Online (Sandbox Code Playgroud)

编辑:

我注意到创建间谍会返回 null,原因尚不清楚:

MapSettingsActivity spy = spy(activityRule.getActivity());
Run Code Online (Sandbox Code Playgroud)

Ser*_*gey 2

首先,这并不是您问题的确切解决方案,但也许会对您有所帮助。

这就是我处理类似问题的方法。一般来说:为了让 Mockito 能够检测到间谍对象上的方法调用,必须在间谍对象上调用此方法(如果您理解我在说什么,因为我不明白))。你的情况并非如此。您的 setLiveLocation 调用了活动的真实实例,该实例存储在 ActivityTestRule 中。

我的示例: 我需要验证 RecyclerView 的 adpter 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))
Run Code Online (Sandbox Code Playgroud)

所以基本上我从 Recycler 获取适配器并将其更改为我的间谍适配器。仅当我进行此替换时,我的测试才成功完成。在您的情况下,ActivityTestRule 保存真实活动的实例,因此您需要以某种方式将其替换为间谍对象。我不知道如何做到这一点,但我想有机会创建此规则的子类,并可能在构造函数中创建活动间谍。然后您将获得监视对象并使用它来验证任何调用。