Does anyone know how to correctly test a channel? ...
# coroutines
d
Does anyone know how to correctly test a channel?
Copy code
coroutinesTestRule.testDispatcher.runBlockingTest {
            var latestNav: NavEvent? = null
            navChannel.consumeEach {
                latestNav = it }
            vm.handleAction(NearbyListingClicked(nearbyListing))
            assertEquals(latestNav, OpenListing(variant.listing!!.wmid.toString()))
        }
But I'm just getting
java.lang.IllegalStateException: This job has not completed yet
The
Channel.consumeEach
appears to be blocking, which I don't think it should be
s
the
navChannel.consumeEach
is not blocking. It is likely suspending (difference there 🙂). I don’t see all of the code, but if
navChannel
is never closed (for sending), the
consumeEach
just keeps being suspended….
You’d need to
launch
a coroutine within your test-scope and that coroutine should send values to
navChannel
and close it when needed.
d
Ah yes that did it thank you! but question, I'm missing something in my understanding
Copy code
navChannel.consumeEach {
                latestNav = it
                navChannel.close()}  }
So adding that block doesn't fix it, same problem, but wrapping it in a
launch
block does fix it, which I understand is because the block is now on a different coroutine, and not blocking the test
But I'm not sure why closing it didn't fix that as well
It needs both the channel.close, and to be launched in a separate coroutine. I get that it needs to be closed due to the way the test dispatcher works, but not why it needs to be launched in a separate one
s
The consumer should not close it. The producer or some other ‘manager’ should. I think you are looking to just get one value from the channel. Just do
latestNav = navChannel.receive()
d
Yup you're right, it felt bad closing itself, thanks!
Copy code
coroutinesTestRule.testDispatcher.runBlockingTest {
            val latestEvent = async { navChannel.receive() }
            vm.handleAction(NearbyListingClicked(nearbyListing))
            assertEquals(latestEvent.await(), OpenListing(variant.listing!!.wmid.toString()))
        }
Ended up going with this and it's all working as expected, thanks!
💯 1