本文介绍了模拟挂起函数在 Mockito 中返回 null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Mockito 模拟了一个挂起函数,但它返回 null

I have a suspending functions that I have mocked, using Mockito but it is returning null

两个项目都使用

'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0'

示例 1

这是我的测试,其中模拟返回 null

here is my test in which the mock is returning null

@Test
fun `when gps not enabled observer is notified`() = runBlocking {
    // arrange
    `when`(suspendingLocationService.getCurrentLocation()).thenReturn(result) // <- when called this returns null

    // act
    presenter.onStartShopButtonClick()

    // assert
    verify(view).observer
    verify(observer).onPrepareShop()
}

我的演示者中有以下实现

I have the below implementation in my presenter

  override suspend fun onStartShopButtonClick() {
    val result = suspendingLocationService.getCurrentLocation() // <- in my test result is null!!!!!!
    view?.apply {
        observer?.onPrepareShop()
        when {
            result.hasGivenPermission == false -> observer?.onStartShop(StoreData(), APIError(APIError.ErrorType.NO_PERMISSION))
            result.hasGPSEnabled == false -> observer?.onStartShop(StoreData(), APIError(APIError.ErrorType.GPS_NOT_ENABLED))
            result.latitude != null && result.longitude != null ->
                storeLocationService.getCurrentStore(result.latitude, result.longitude) { store, error ->
                    observer?.onStartShop(store, error)
                }
        }
    }
}

但是我相信下面的一个非常相似的实现

however I have what I believe to a very similar implementation that is working below

示例 2

下面的测试确实通过了,正确的函数确实响应了一个产品

The below test does pass and the correct the function does respond with a product

@Test
fun `suspending implementation updates label`() = runBlocking {
    // arrange
    `when`(suspendingProductProvider.getProduct("testString")).thenReturn(product)

    // act
    presenter.textChanged("testString")

    // assert
    verify(view).update(product.name)
}

这里是presenter的实现

here is the implementation of the presenter

override suspend fun textChanged(newText: String?) {
    val product = suspendingNetworkProvider.getProduct(newText)
    view?.update(product.name)
}

这是我正在模拟的界面

interface SuspendingProductProvider {
    suspend fun getProduct(search: String?): Product
}

在第一个示例中我没有做的事情

what I am not doing in the first example

推荐答案

Mockito 对 suspend 函数有特殊的支持,但在 Kotlin 1.3 中,协程在内部的实现方式发生了一些变化,因此较旧Mockito 版本不再识别由 Kotlin 1.3 编译的 suspend 方法.并且 kotlinx.coroutines 从 1.0.0 版本开始使用 Kotlin 1.3.

Mockito has a special support for suspend functions, but in Kotlin 1.3 there were some changes in how coroutines are implemented internally, so older versions of Mockito are no longer recognize suspend methods compiled by Kotlin 1.3. And kotlinx.coroutines use Kotlin 1.3 since version 1.0.0.

在 Mockito 中添加了相应的支持,但只有 从 2.23 版开始,因此更新您的 Mockito 版本会有所帮助.

Corresponding support was added to Mockito, but only since version 2.23, so updating your Mockito version will help.

这篇关于模拟挂起函数在 Mockito 中返回 null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 20:58