当你使用
launch
,您正在创建一个将执行
异步
. 使用
runBlocking
不会影响到这一点。
你的测试失败是因为你发布的东西
会发生的
,但还没有发生。
在执行任何断言之前,确保启动已执行的最简单方法是调用
.join()
在他们身上。
fun someLaunch() : Job = launch {
foo()
}
@Test
fun `test some launch`() = runBlocking {
someLaunch().join()
verify { foo() }
}
而不是拯救个人
Jobs
在你的
ViewModel
,在
onCleared()
你可以实现你的
CoroutineScope
就像这样:
class MyViewModel : ViewModel(), CoroutineScope {
private val job = SupervisorJob()
override val coroutineContext : CoroutineContext
get() = job + Dispatchers.Main
override fun onCleared() {
super.onCleared()
job.cancel()
}
}
所有发生在
协同视野
成为那个的孩子
协同视野
,所以如果你取消
job
(有效地取消了
协同视野
),然后取消在该范围内执行的所有协同程序。
所以,一旦你把你的
协同视野
实施,你可以
视图模型
函数只是返回
Job
学生:
fun loadSomeObjects1() = launch {
val objects1Result = repository.getSomeObjects1Async()
objects1.value = objects1Result
}
现在你可以用
.join()
:
@Test
fun `loadObjects1 should get objects1`() = runBlocking {
viewModel.someObjects1.observeForever(observer)
val expectedResult = listOf(SomeObject("test1"))
`when`(repository.getSomeObjects1Async())
.thenReturn(expectedResult)
viewModel.loadSomeobjects1().join()
verify(observer).onChanged(listOf(SomeObject("test1")))
}
我也注意到你在使用
Dispatchers.Main
为了你的
视图模型
. 这意味着默认情况下,您将在主线程上执行所有协程。你应该考虑一下这是否真的是你想做的事情。毕竟,Android中很少有非UI操作需要在主线程上完成,而且ViewModel不应该直接操作UI。