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.