Ridwan Farouki
04/23/2022, 10:03 PMCoroutineScope
to use a `TestScope`'s scheduler in kotlinx-coroutines-test:1.6.1
for the virtual time behaviour? I would have expected CoroutineScope(Job() + testScheduler)
to work but it doesn't. (Note that CoroutineScope(Job() + coroutineContext)
does work but then when I try to cancel differentScope
it fails the test because it cancels the parent TestScope
, making it hard to test code that uses structured concurrency)
fun tickTest() = runTest {
val differentScope = CoroutineScope(Job() + testScheduler)
val ticks = mutableListOf<Int>()
val tickJob = differentScope.launch {
var time = 0
while (true) {
delay(1_000)
ticks.add(++time)
}
}
advanceTimeBy(5_001)
tickJob.cancel()
println(ticks)
assert(ticks.size == 5)
}
julian
04/23/2022, 10:18 PMval differentScope = CoroutineScope(Job() + coroutineContext[ContinuationInterceptor]!!)
julian
04/23/2022, 10:33 PMdelay
implementation needed for virtual time.Ridwan Farouki
04/23/2022, 10:40 PMjulian
04/23/2022, 10:48 PMCoroutineScope(Job() + coroutineContext)
cancels the TestScope
job is that the rightmost context element wins when adding.
Since coroutineContext
is rightmost and contains a job, that job overwrites the one on the left of the +
.
This, though, would do what you want: CoroutineScope(coroutineContext + Job())
, and then later, differentScope.cancel()
.Ridwan Farouki
04/24/2022, 12:37 AM+
operator is not commutative caught me off guard.Dmitry Khalanskiy [JB]
04/25/2022, 7:14 AMCoroutineScope(StandardTestDispatcher(testScheduler) + Job())
(here, the order doesn't matter), or even just CoroutineScope(StandardTestDispatcher(testScheduler))
because CoroutineScope
adds a Job
if none is specifie. This creates a new dispatcher that is linked to the test framework.