https://kotlinlang.org logo
Title
f

Florian Walther (live streaming)

01/05/2022, 12:25 PM
How would you test this countdown timer based on coroutines? What can I use as the time source because I can't use
SystemClock.elapsedRealtime
in a test.
fun startTimer(
    millisInFuture: Long,
    countDownInterval: Long,
    onTick: (millisUntilFinished: Long) -> Unit,
    onFinish: () -> Unit,
) {
    millisUntilFinished = millisInFuture
    timerJob = scope.launch {

        val startTime = timeSource.elapsedRealTime
        val targetTime = startTime + millisInFuture
        while (true) {
            if (timeSource.elapsedRealTime < targetTime) {
                delay(countDownInterval)
                millisUntilFinished = targetTime - timeSource.elapsedRealTime
                onTick(millisUntilFinished)
            } else {
                onFinish()
            }
        }
    }
}
SystemClock time is needed because
delay
is not exact
I can create a fake time source that uses a Long field, but I don't know how to increment it in my test
l

louiscad

01/05/2022, 12:42 PM
Inject the time source so you can control it from the test
f

Florian Walther (live streaming)

01/05/2022, 12:46 PM
that's what we are doing but I don't know how to use that in the test properly
we always end up stuck in some loop or don't increment the time at all
l

louiscad

01/05/2022, 12:52 PM
Maybe raceOf can help you, where one coroutine is the test, and the other is the time control: https://blog.louiscad.com/coroutines-racing-why-and-how
f

Florian Walther (live streaming)

01/07/2022, 10:34 AM
Thank you for the link!