myanmarking
09/13/2019, 12:45 PMclass TestExample {
class Example {
var counter: Int = 0
fun startCounter() {
val coroutineScope = CoroutineScope(Dispatchers.Unconfined)
coroutineScope.launch {
while (counter <= 100) {
counter += 1
delay(100)
}
}
}
}
@Test
fun `test 1`() = runBlockingTest {
val example = Example()
example.startCounter()
Assert.assertEquals(1, example.counter)
advanceTimeBy(150) // fails
// Thread.sleep(150) // works
Assert.assertEquals(2, example.counter)
}
}
Paulius Ruminas
09/13/2019, 12:59 PMval coroutineScope = CoroutineScope(Dispatchers.Unconfined)
so you must wait for 100ms.myanmarking
09/13/2019, 12:59 PMPaulius Ruminas
09/13/2019, 1:02 PMclass Example {
var counter: Int = 0
suspend fun startCounter(scope: CoroutineScope) {
scope.launch {
while (counter <= 100) {
counter++
delay(100)
}
}
}
}
@Test
fun `test 1`() = runBlockingTest {
val example = Example()
example.startCounter(this@runBlockingTest)
Assert.assertEquals(1, example.counter)
advanceTimeBy(150)
Assert.assertEquals(2, example.counter)
}
runBlockingTest
creates a coroutine scope for running tests val scope = TestCoroutineScope(safeContext)
. If you do not reuse this scope then you don't have a virtual clock anymore and you actually have to wait for the specified delay.myanmarking
09/13/2019, 1:10 PMgergo
09/13/2019, 1:38 PMmyanmarking
09/13/2019, 1:39 PMgergo
09/13/2019, 1:41 PMclass Example(private val coroutineScopeFactory : () -> CoroutineScope = { CoroutineScope(Dispatchers.Unconfined) })
...
then in test you could swich it out like
Example{ this@runBlockingTest }
in your method would look like
val coroutineScope = coroutineScopeFactory()
myanmarking
09/13/2019, 1:45 PM