繁体   English   中英

如何使用 MockK 测试暂停 function?

[英]How to test suspend function using MockK?

我正在为我的 Datarepository 层编写一个单元测试,它只是调用一个接口。 我正在使用 Kotlin、协程和 MockK 进行单元测试。 在 MockK 中,如何验证我是否调用apiServiceInterface.getDataFromApi()并且只发生了一次? 我应该把代码放在 runBlocking 中吗?

这是我的代码:

单元测试

import com.example.breakingbad.api.ApiServiceInterface
import com.example.breakingbad.data.DataRepository
import io.mockk.impl.annotations.InjectMockKs
import io.mockk.impl.annotations.MockK
import io.mockk.verify
import org.junit.Test

存储库

class DataRepositoryTest {
    @MockK
    private lateinit var apiServiceInterface: ApiServiceInterface

    @InjectMockKs
    private lateinit var dataRepository: DataRepository

    @Test
    fun getCharacters() {
            val respose = dataRepository.getCharacters()
            verify { apiServiceInterface.getDataFromApi() }
    }
}

    class DataRepository @Inject constructor(
    private val apiServiceInterface: ApiServiceInterface
) {
    suspend fun getCharacters(): Result<ArrayList<Character>> = kotlin.runCatching{
        apiServiceInterface.getDataFromApi()
    }
}

界面

interface ApiServiceInterface {
    @GET("api/characters")
    suspend fun getDataFromApi(): ArrayList<Character>
}

是的,您应该将dataRepository.getCharacters()调用放在runBlocking

并且应该将verify替换为coVerify

最后,测试应该是这样的:

@Test
fun getCharacters() {
    val respose = runBlocking { dataRepository.getCharacters() }
    
    coVerify { apiServiceInterface.getDataFromApi() }
}

此外,由于您只想验证它只发生过一次,因此您需要使用精确参数coVerify(exactly = 1)调用coVerify

我认为您应该更喜欢使用runTest而不是runBlockingrunBlockingTest 。简要告诉您这三个。

  1. runBlocking允许你通过阻塞一个新的协程来调用挂起函数,它会阻塞当前线程直到它完成。

  2. runBlockingTest将立即执行暂停的 function 跳过任何延迟并立即进入协程块,而runBlocking将等待延迟量

自 kotlinx.coroutines 1.6.0 版本以来, 由于迁移指南中列出的这些原因,不推荐使用runBlockingTest以支持runTest

  1. runTest()将自动跳过对 delay() 的调用并处理未捕获的异常。 与 runBlockingTest() 不同,它将等待异步回调来处理某些代码在未与测试模块集成的调度程序中运行的情况。

我希望能回答您关于在这 3 个中选择什么来测试您的暂停 function 的问题。 你的代码看起来像这样-:

@Test
fun getCharacters() = runTest {
    val response = dataRepository.getCharacters()
    
    coVerify { apiServiceInterface.getDataFromApi() }
}

另请注意,正如 David 上面提到的那样,因为 getDataFromApi() 也是异步/暂停 function ,所以您将不得不使用 coVerify 而不是 verify 来模拟它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM