模拟的暂停功能在Mockito中返回null

Mar*_*ist 5 junit mockito kotlin kotlinx.coroutines

我有一个使用Mockito模拟的暂停函数,但它返回null

两个项目都使用

'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0'
Run Code Online (Sandbox Code Playgroud)

例子1

这是我的测试中模拟返回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()
}
Run Code Online (Sandbox Code Playgroud)

我的演示者中有以下实现

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

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

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

here is the implementation of the presenter

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

here is the interface I am mocking

interface SuspendingProductProvider {
    suspend fun getProduct(search: String?): Product
}
Run Code Online (Sandbox Code Playgroud)

what I am not doing in the first example

qww*_*sad 10

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

相应的支持已添加到Mockito,但仅从2.23版本开始,因此更新Mockito版本将有所帮助。

  • 我正在使用 org.mockito:mockito-core:3.3.0,但仍然有这个问题 (4认同)

Vah*_*iri 6

首先获取Mockito-kotlin并在mockito 中,当您想要模拟挂起函数时可以使用此代码:

        val mockedObject: TestClass = mock()
        mockedObject.stub {
            onBlocking { suspendFunction() }.doReturn(true)
        }
Run Code Online (Sandbox Code Playgroud)