我正在尝试测试一个声明为CoroutineScope
的类。该类的某些方法可以在其范围内launch
进行作业,我必须从测试方法中断言这些作业的效果。
这是我尝试过的:
import kotlinx.coroutines.*
class Main : CoroutineScope {
override val coroutineContext get() = Job()
var value = 0
fun updateValue() {
this.launch {
delay(1000)
value = 1
}
}
}
fun main() {
val main = Main()
val mainJob = main.coroutineContext[Job]!!
main.updateValue()
runBlocking {
mainJob.children.forEach { it.join() }
}
require(main.value == 1)
}
我期望updateValue()
将在coroutineContext
中创建根作业的子级。但是事实证明mainJob.children
为空,所以我等不及launch
的完成,而require
语句失败了。
完成这项工作的正确方法是什么?
答案 0 :(得分:1)
我的代码中的错误很简单:
override val coroutineContext get() = Job()
我不小心留下了一个自定义吸气剂,这意味着对coroutineContext
的每次访问都会创建一个新作业。自然,我在测试代码中找到的工作没有孩子。删除get()
可使代码起作用:
override val coroutineContext = Job()
答案 1 :(得分:0)
将协程生成器启动修改为
this.launch(start = CoroutineStart.LAZY)
并将您的工作对象初始化更改为直接
override val coroutineContext : Job = Job()
它应该产生预期的结果
这是我尝试的示例,它产生了预期的结果
import kotlinx.coroutines.*
import kotlin.coroutines.CoroutineContext
class Main : CoroutineScope {
val scope: CoroutineScope = this
override val coroutineContext = Job()
//Dispatchers.Default +
var value = 0
fun updateValue(csc : CoroutineScope) {
csc.launch(context = coroutineContext, start = CoroutineStart.LAZY) { println(this.coroutineContext[Job]!!.toString() + " job 2") }
csc.launch (context = coroutineContext, start = CoroutineStart.LAZY){ println(this.coroutineContext[Job]!!.toString() + " job 3") }
csc.launch (start = CoroutineStart.LAZY){
println(this.coroutineContext[Job]!!.toString() + " job 1")
//delay(1000)
value = 1
}
}
fun something() {
launch (start = CoroutineStart.LAZY){
println(this.coroutineContext[Job]!!.toString() + " something 1")
}
launch (start = CoroutineStart.LAZY){
println(this.coroutineContext[Job]!!.toString() + " something 2")
}
launch(start = CoroutineStart.LAZY) {
println(this.coroutineContext[Job]!!.toString() + " something 3")
delay(2000)
value = 1
}
}
}
fun main() {
val main = Main()
val mainJob = main.coroutineContext[Job]!!
main.updateValue(main.scope)
//main.something()
runBlocking {
//println(mainJob.children.count())
println(mainJob.children.count())
mainJob.children.forEach {
//println("in run blocking")
println(it.toString())
it.join()
}
}
println(main.value)
}
`