提问人:BRDroid 提问时间:9/1/2021 最后编辑:TomerikooBRDroid 更新时间:7/30/2022 访问量:9788
如何使用 MockK 测试挂起函数?
How to test suspend function using MockK?
问:
我正在为我的 Datarepository 层编写一个单元测试,它只是调用一个接口。
我正在使用 Kotlin、协程和 MockK 进行单元测试。
在 MockK 中,我如何验证我是否打过电话并且只发生过一次?
我应该把代码放在 runBlocking 中吗?apiServiceInterface.getDataFromApi()
这是我的代码:
单元测试
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() }
}
此外,由于您要验证它只发生过一次,因此您需要使用 exact 参数进行调用coVerify
coVerify(exactly = 1)
我认为您应该更喜欢使用 而不是 or 。简单介绍一下这三个。runTest
runBlocking
runBlockingTest
runBlocking
允许您通过阻止新的协程来调用挂起函数,并阻止当前线程,直到它完成。runBlockingTest
将立即执行暂停函数,跳过任何延迟并立即进入协程块,这与将等待延迟量不同runBlocking
由于迁移指南中列出的这些原因,kotlinx.coroutines 1.6.0 版本已被弃用,取而代之的是。runBlockingTest
runTest
runTest()
将自动跳过对 delay() 的调用并处理未捕获的异常。与 runBlockingTest() 不同,它将等待异步回调来处理某些代码在未与测试模块集成的调度器中运行的情况。
我希望这能回答您在这 3 个中选择什么来测试您的挂起函数的问题。您的代码将如下所示 - :
@Test
fun getCharacters() = runTest {
val response = dataRepository.getCharacters()
coVerify { apiServiceInterface.getDataFromApi() }
}
另请注意,正如上面提到的 David,因为 getDataFromApi() 也是异步/挂起函数,因此您必须使用 coVerify 而不是 verify 来模拟相同的函数。
评论