Is it possible to create a test that terminates wh...
# coroutines
s
Is it possible to create a test that terminates when all the fire & forgot coroutines in the test have completed? 🧵
I’m trying to create a function that stays after the return of a particular function and handles asynchronous side effects. These side effects are handled in a
fire and forget
kind of way in production code, but in a test code I want to make sure that these side effects have been successfully terminated.
Unfortunately, I can’t create a function that returns
List<Deferred>
of side effects because my actual usage requires me to create an endpoint and test it e2e via spring framework.
j
Call
.join
on the
Job
The scope has a context and the context has a job. Although there's probably an extension on the scope directly to join...
Another thing you can do, though, is just use
coroutineScope { endpoint(this) }
and then you're done
that function joins on the job automatically and thus waits for all coroutines to finish
s
Another thing you can do, though, is just use
coroutineScope { endpoint(this) }
and then you’re done
This is what I wanted most, but since the call to the endpoint is actually through the spring framework, it is difficult to pass the coroutineScope or context, so I was looking for a way to pass the coroutineScope as a function argument (it do not support that kind of coroutine e2e testings...).
Call
.join
on the
Job
I think this is working in my codes, I will try this in my codes! Thank you for kind answers blob smile happy
j
Something we do with our Spring tests is this: 1. we have a little wrapper that adds a timeout to each of our tests to ensure that no test can hang our build forever:
Copy code
fun runTest(wait: Duration = 120.seconds, context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> Unit) {
    runBlocking(context) {
        try {
            withTimeout(wait, block)
        } catch (e: TimeoutCancellationException) {
            throw IllegalStateException("test timed out after ${wait}", e)

        }
    }
}
2. We put assertions in an
eventually
block (comes with kotest assertions). So we can simply assert something should have happened and it will just poll until that becomes true or the test times out. Great for testing asynchronous side effects.
so most of our tests look like this:
Copy code
fun shouldTest() = runTest {
...
eventually {
}
...

}