Akram Raza
03/08/2024, 5:24 PMEvghenii
03/08/2024, 5:27 PM@Test
fun someTest() = runTest {
mockkObject(OtherObject)
every { OtherObject.someSharedFlow } returns testSharedFlow.asSharedFlow()
mockkObject(ThirdObject)
every { ThirdObject.doSomeStuff() } answers {}
val myClass = MyClass(StandardTestDispatcher(testScheduler))
myClass.start()
advanceTimeBy(100L)
testSharedFlow.emit(SomeEvent()).also {
advanceTimeBy(100L)
verify { ThirdObject.doSomeStuff() } // this fails
}
myClass.stop() // stops the coroutines
unmockkObject(ThirdObject)
unmockkObject(OtherObject)
}
Akram Raza
03/08/2024, 5:32 PMAkram Raza
03/08/2024, 5:34 PMAkram Raza
03/08/2024, 5:40 PMEvghenii
03/08/2024, 7:19 PMAnd delay is skipped in runTestSo that's why it happens. I still hoped that a delay will move current coroutine to the end of the queue, even if it doesn't wait, but apparently it doesn't? Looks like a potential improvement to me. Anyway, I need that coroutine to run until the coroutine is stopped from outside. I'll think of a refactor to make it testable.
Evghenii
03/08/2024, 7:19 PMAkram Raza
03/08/2024, 8:09 PMEvghenii
03/08/2024, 9:23 PMAkram Raza
03/09/2024, 3:36 AMEvghenii
03/09/2024, 8:44 PMimport kotlinx.coroutines.runBlocking
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.CoroutineScope
val scope = CoroutineScope(Dispatchers.Default.limitedParallelism(1))
val sharedFlow = MutableSharedFlow<Int>()
fun main() {
val job = scope.launch {
val whileJob = scope.launch {
var i = 0
while (i < 10) {
println("While loop $i, thread ${Thread.currentThread().getName()}")
delay(100L)
i++
}
}
scope.launch {
sharedFlow.collect { i ->
println("Shared flow $i, thread ${Thread.currentThread().getName()}")
}
}
repeat(10) { i->
sharedFlow.emit(i)
delay(50L)
}
whileJob.join()
}
runBlocking {
job.join()
}
}
Evghenii
03/09/2024, 8:47 PMWhile loop 0, thread DefaultDispatcher-worker-1
Shared flow 1, thread DefaultDispatcher-worker-1
Shared flow 2, thread DefaultDispatcher-worker-1
While loop 1, thread DefaultDispatcher-worker-1
Shared flow 3, thread DefaultDispatcher-worker-1
Shared flow 4, thread DefaultDispatcher-worker-1
While loop 2, thread DefaultDispatcher-worker-1
Shared flow 5, thread DefaultDispatcher-worker-1
Shared flow 6, thread DefaultDispatcher-worker-1
While loop 3, thread DefaultDispatcher-worker-1
Shared flow 7, thread DefaultDispatcher-worker-1
Shared flow 8, thread DefaultDispatcher-worker-1
While loop 4, thread DefaultDispatcher-worker-1
Shared flow 9, thread DefaultDispatcher-worker-1
While loop 5, thread DefaultDispatcher-worker-1
While loop 6, thread DefaultDispatcher-worker-1
While loop 7, thread DefaultDispatcher-worker-1
While loop 8, thread DefaultDispatcher-worker-1
While loop 9, thread DefaultDispatcher-worker-1
But that's because this is not a test dispatcher, and so delay does release the thread, and the thread does run other coroutines whenever they are ready.Evghenii
03/09/2024, 8:49 PMEvghenii
03/11/2024, 3:26 PM