在Mockito中模拟挂起函数返回空值

f4t66c6m  于 2022-11-08  发布在  其他
关注(0)|答案(4)|浏览(245)

我有一个挂起的函数,我已经模拟,使用Mockito,但它是返回空
两个项目都使用

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

实施例一
这是我的测试,其中mock返回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()
}

我的演示文稿中包含以下实现

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)
                }
        }
    }
}

但是,我认为下面的实现非常类似
实施例二
以下测试通过,并且功能正确响应产品

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

    // act
    presenter.textChanged("testString")

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

下面是演示器的实现

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

这是我正在模仿的界面

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

我在第一个例子中没有做的

carvr3hs

carvr3hs1#

Mockito特别支持suspend函数,但在Kotlin 1.3中,协程的内部实现方式发生了一些变化,因此旧版本的Mockito不再识别由Kotlin 1.3编译的suspend方法。
Mockito中增加了相应的支持,但从2.23版本开始才有,所以更新Mockito版本会有所帮助。

zpf6vheq

zpf6vheq2#

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

val mockedObject: TestClass = mock()
        mockedObject.stub {
            onBlocking { suspendFunction() }.doReturn(true)
        }
x8diyxa7

x8diyxa73#

你可以在初始化时模拟多个函数。比如说,我们有一个仓库:

interface ContactRepository {
    suspend fun getContact(contactId: Long): Contact
    fun getContactsFlow(): Flow<List<Contact>>
}

你可以在适当的地方嘲弄两种方法:

val testContact = ContactModel(testId)
val repository: ContactRepository = mock {
    onBlocking { getContact(testId) } doReturn testContact
    on { getContactsFlow() } doReturnFlow flowOf(listOf(testContact))
}
jtw3ybtb

jtw3ybtb4#

我升级到mockito 2.23并成功地做到了这一点,没有遇到空值的问题。

class Parser {
suspend fun parse(responseBody: ByteArray) : Result = coroutineScope {/*etc*/}
}

val expectedResult = Mockito.mock(Result::class.java)
Mockito.`when`(mockParser.parse(byteArrayOf(0,1,2,3,4))).thenReturn(coroutineScope {
 expectedResult
})

相关问题