Is it possible to catch exceptions thrown in a `ba...
# coroutines
z
Is it possible to catch exceptions thrown in a
backgroundScope
before
runTest { }
completes, and prevent it from throwing that exception at the end of the
runTest { }
function?
I want the allowing of uncompleted active coroutines that
backgroundScope
provides, but with the the inline exception throwing of
TestScope
and
UnconfinedTestDispatcher
My use case is that I want to leverage some type of
assertFailsWith(..)
logic on the exceptions that occurred before runTest completes
I don’t like having to wrap the
runTest { }
in an
assertFailsWith<Exception>{ }
.
Copy code
// this works
@Test
fun currentSolution() {
    assertFailsWith<IllegalStateException> {
        executeTest {
            // executed on a background scope
            whenExceptionIsIntentionallyThrown()
        }
    }
}
I would prefer to be able to do something like this:
Copy code
// does not work
@Test
fun doesNotCatchException() = executeTest {
    // executed on a background scope
    whenExceptionIsIntentionallyThrown()
    
    assertFailsWith<IllegalStateException> {
        thenIllegalStateExceptionWasThrown()
    }
}
I need to access the exceptions thrown under the
backgroundScope
before
runTest { }
completes. Is it possible?
c
Why do you want to assert the behavior of the background scope? The background scope is meant to model tasks that are independent of the system-under-test. What you're trying to test is intended to run in the foreground scope, so this seems to be a X/Y problem.
z
The background scope is meant to model tasks that are independent of the system-under-test
what do you mean by this? we have a lot of ongoing actor coroutines in our codebase that build ongoing state. we don’t care about manually closing these. In production,
scope.cancel()
is meant to gracefully shut down these actor coroutines. My understanding is that this is what
backgroundScope
is for. Am I wrong here?
c
Your actors should always gracefully terminate when their input channels close, right? If so, I'd have all actors run in the foreground scope, and they will gracefully terminate at the end of the test when all data has been processed This way you will also be able to detect actors that stay alive even after their work is done