Hi, im trying to write some tests around some code...
# flow
a
Hi, im trying to write some tests around some code that delays before taking an action. however, delays are skipped when using
runTest
and its making testing the timeout impossible. am i missing something? im trying to use
advanceTimeBy
to maneuver around this delay for tests but it seems useless as the delays are just skipped
c
What is the timeout for? How does the system behave differently depending on whether the timeout finished or not?
a
a lamda is run if the timeout completes
and the timeout completes if a flow doesn't emit in that time window
Copy code
fun <T: Any> Flow<T>.ifDelayed(timeMillis: Long, block: () -> Unit): Flow<T> = channelFlow {
     val delayJob = launch {
         delay(timeMillis)
         block()
     }
 
     collect {
         delayJob.cancelAndJoin()
         send(it)
     }
 }
may not be correct, found an answer on stackoverflow that I'm still working to adapt and understand, and testing it properly is a part of that process
c
How I would do it:
Copy code
@Test
fun lambdaIsNotCalledIfTimeoutDidntEnd() = runTest {
    var called = false
    flow {
        delay(100)
        emit(Unit)
    }.ifDelayed(1000) {
        called = true
    }.collect()
    assertFalse(called)
}

@Test
fun lambdaIsCalledIfTimeoutEnds() = runTest {
    var called = false
    flow {
        delay(5000)
        emit(Unit)
    }.ifDelayed(1000) {
        called = true
    }.collect()
    assertTrue(called)
}
a
ooh brilliant
the thing for me here is understanding advanceTimeBy is useless for testing delays
1
c
It's not useless, it's just that what you want to test is whether the lambda is called or not. You don't really care about the control of time at all
In general, I recommend testing the effect of things rather than the things themselves. It's called black box testing, if you want to read more about it
k
You don’t really care about the control of time at all
I think in many cases you actually do! So, I would agree that
advanceTimeBy
doesn’t appear to be very helpful in situations like this. I’ve noticed a common sentiment among developers, including myself, who are confused about what
advanceTimeBy
is supposed to do and how to use it.