Unit testing a Kotlin coroutine with delay

If you don’t want any delay, why don’t you simply resume the continuation in the schedule call?:

class TestUiContext : CoroutineDispatcher(), Delay {
    override fun scheduleResumeAfterDelay(time: Long, unit: TimeUnit, continuation: CancellableContinuation<Unit>) {
        continuation.resume(Unit)
    }

    override fun dispatch(context: CoroutineContext, block: Runnable) {
        //CommonPool.dispatch(context, block)  // dispatch on CommonPool
        block.run()  // dispatch on calling thread
    }
}

That way delay() will resume with no delay. Note that this still suspends at delay, so other coroutines can still run (like yield())

@Test
fun `test with delay`() {
    runBlocking(TestUiContext()) {
        launch { println("launched") }
        println("start")
        delay(5000)
        println("stop")
    }
}

Runs without delay and prints:

start
launched
stop

EDIT:

You can control where the continuation is run by customizing the dispatch function.

Leave a Comment