android - Espresso/Mockito 验证该方法是否被调用

标签 android mockito android-espresso

我有一个使用 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/

相关文章:

android - 如何删除父 View - android

java - 如何通过 Mockito 验证是否使用预期参数(java.util.List 作为参数)调用了方法

java - Mockito:方法的返回值取决于调用的其他方法

android - 如何在 Mockito3.x 中使用 PowerMock?

android - Espresso : how to scroll to the bottom of ScrollView

android - 由于 'android.content.res.Resources$NotFoundException',检测运行失败

android - 如何使用 Espresso 单击回收站 View 项目中的按钮?

java - 从某些示例线程代码中获取 RuntimeException

android - 信号 11 (SIGSEGV),代码 1 (SEGV_MAPERR) libwebviewchromium.so

java - 如何将数据从 Activity 传递到抽屉导航 Android 内的 fragment