# coroutines

Patrick Ramsey

08/26/2021, 1:02 AM
I’m sorry to keep spamming this channel. I’ll try and keep it down after this. But: I’m having real trouble wrapping my head around the semantics of test dispatchers, specifically around how to test code that involves multiple dispatchers. From a test, I’m trying to call <some channel>.send(<some object>). This yields, which seems to cause dispatcher.advanceUntilIdle() to return (since the consumer is running on another dispatcher), which causes the test dispatcher to try to clean up and exit (even though the test isn’t finished), which causes it to throw IllegalStateException (as if the test had ended). I assume this is it functioning as it’s supposed to, but it leaves me at a little bit of a loss as to how to test this functionality.
TL;DR: calling channel.send() from my test seems to be causing my TestCoroutineDispatcher to shut down before I’m done using it. I’d love some insight as to why.
Okay, literally the following test fails:
Copy code
@Test fun `this seems like it shouldnt fail`() = runBlockingTest {
    val c = Channel<Unit>()

Running this test, all on its own, fails with IllegalStateException: “This job has not completed yet”. Why would that be?
Changing it to a buffered channel seems to have fixed the test so I assume it has something to do with the way the two coroutines interact when the sender on a RENDEZVOUS channel is waiting for the receiver.
I think I get it. In the above case, send() yields until another coroutine calls receive(). There has to be another coroutine running, or send() will never return (ie, no further work will be scheduled). Because there’s no further work scheduled (but the coroutine hasn’t exited), the test fails. In the case of my test, though, the issue was that there was a consumer, but it was running on another dispatcher, so from the perspective of runBlockingTest’s dispatcher there was no further work scheduled, so it failed in the same way.
Ick. Found the actual issue. Sorry again, folks, for the noise.