【问题标题】:mockito wanted but not invoked, Actually there were zero interactions with this mockmockito 想要但没有被调用,实际上与这个 mock 的交互为零
【发布时间】:2021-08-30 02:03:23
【问题描述】:

我很抱歉就这个错误发了另一个帖子,但我仔细检查了另一个帖子并确保它不是同一个原因。

我有一个使用ExploreServiceExploreRepository 类。存储库实现 NetworkBoundResource。我是单元测试仓库,使用 Mockito 来模拟 Service。


class ExploreRepository(
    private val context: Context,
    private val exploreService: ExploreService
) {
    
    suspend fun getProperties(southwest: LatLng, northeast: LatLng, zoomLevel: Float): LiveResource<List<Property>> {
        return object : NetworkBoundResource<List<Property>, SearchProperties>() {


            override suspend fun makeApiCall(): SearchProperties {
                println("exploreService hashcode ${System.identityHashCode(exploreService)}")
                return exploreService.getProperties(context, geoHashList, precision)
            }

        }.asLiveResource()
    }

我的 testExploreRepository 类


@Config(sdk = intArrayOf(Build.VERSION_CODES.O_MR1))
@RunWith(AndroidJUnit4::class)
class ExploreRepositoryTest {


    ...
    // Subject under test
    private lateinit var exploreRepository: ExploreRepository

    // Use a fake service to be injected into the repository
    private lateinit var mockExploreService: ExploreService

    private lateinit var mockSearchProperties: SearchProperties

    private val context: Application = ApplicationProvider.getApplicationContext()

    @Before
    fun setup(){
        mockExploreService = mock()
        exploreRepository = ExploreRepository(context, mockExploreService)
        mockSearchProperties = mock()
    }

    @Test
    fun `should make network service call`() = runBlocking<Unit> {

        // stubbing
        whenever(mockExploreService.getProperties(any(), any(), any())).thenReturn(mockSearchProperties)

        val northeast = LatLng( 37.799001, -122.422889)
        val southwest = LatLng( 37.782180, -122.451554)
        val zoomLevel = 10f

        exploreRepository.getProperties(southwest,northeast,zoomLevel)
        println("exploreService hashcode ${System.identityHashCode(mockExploreService)}") // debug line
        verify(mockExploreService, times(1)).getProperties(any(), any(), any())
    }
}

我已经打印出 exploreService 的 hashCode。 makeApiCall() 中的println("exploreService hashcode ${System.identityHashCode(exploreService)}") 确实运行了。 而且我确保我在我的存储库中调用相同的模拟服务实例。 但是mockito仍然抛出Actually, there were zero interactions with this mock.

编辑:实际上在测试文件中,启用了 println() 调试行。错误消失了。没有它会抛出错误。有什么线索吗?

【问题讨论】:

    标签: android unit-testing mockito


    【解决方案1】:

    我认为您正在尝试使用协程测试策略来测试回调实现。因此,测试可能在回调中调用模拟之前完成。此外,您正在从挂起方法返回一个“LiveResource”,所以也许您应该使用它并在返回时验证而不是检查模拟,因为您确实在方法内创建了一个对象

    【讨论】:

    • 谢谢,但存储库实现不是回调,它是 NetworkboundResource 抽象类的实现。 NetworkboundResource 的构造函数将调用 makeApiCall 函数。甚至 makeApiCall 函数中的 printlin() 也确实运行了。
    • 你说得对,这是一个时间问题。如果我用 sleep(20) 替换该 prinln(),则测试通过。可能是因为我们在 NetworkBoundResource 中使用协程挂起,verify() 在 NetworkBoundResource 调用 makeApiCall() 之前被调用
    • 将您的标记为已接受,因为您在正确的轨道上。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多