【发布时间】:2018-08-03 01:38:45
【问题描述】:
有没有办法让我模拟一个挂起函数,这样它就不会发出数据,否则会发出错误。使用 RxJava 2,我可以模拟该函数以返回 Observable.error 或 Observable.never,但我在 kotlin 协程中找不到等效的功能。这是需要模拟的函数。
override suspend fun execute(param: Params): List<NewsModel> {
return dataManager.getNewsCoro(param.newsType)
}
从我的 viewModel 我以这种方式调用挂起函数
fun getNews(newsType: NewsType) {
liveData.postValue(NewsViewState(AsyncViewResource.loading()))
launch {
tryCatchFinally({
val newsList = getNews.execute(GetNewsCoro.Params(newsType))
liveData.postValue(NewsViewState(AsyncViewResource.success(newsList)))
}, {
liveData.postValue(NewsViewState(AsyncViewResource.error(it)))
}, {}, false)
}
}
在该视图模型的测试类中,我想模拟执行函数,使其永远不会返回数据,这样我就可以测试传递给 liveData 的数据是否是我所期望的。在 RxJava 中,我可以模拟返回 Observable.never() 和 Observable.error() 的函数。但是对于协程,我迷失了寻找模拟它的方法。
【问题讨论】:
-
我不知道模拟如何与可挂起函数进行互操作,但让它不返回任何内容是微不足道的:
suspend fun execute(...): List<NewsModel> { suspendCoroutine<Unit> {}; return whatever // you'll never reach this } -
@MarkoTopolnik 如果你这样做,测试永远不会因为线程被阻塞而结束?
-
仅当您将其设置为等待协程完成时,例如使用
runBlocking。您可以使用launch(Unconfined),它将立即运行您的协程,直到第一个暂停点。那么你不需要将它包装在runBlocking中,并且没有线程会阻塞。 -
但是要使用 mocktio 模拟函数,您必须使用 runBlocking。否则由于螺纹不同。你不能确定它是否真的被嘲笑了。
-
听起来你也想要你的蛋糕并吃掉它。如果你永远挂起协程,那么
runBlocking将永远阻塞。您可以在清理中取消您从launch获得的作业。
标签: android unit-testing kotlin mockito kotlinx.coroutines