Why does the following code crash with a null exce...
# coroutines
t
Why does the following code crash with a null exception?
Copy code
val channel = ConflatedBroadcastChannel(Unit)
channel.asFlow().produceIn(GlobalScope).poll()!!
If I understand correctly this shouldn’t be happening because the channel has a default
Unit
value. The following code, however, does not crash:
Copy code
val channel = ConflatedBroadcastChannel(Unit)
channel.openSubscription().poll()!!
I don’t get why this works but the first example doesn’t. Could someone please explain this behaviour?
g
In which thread do you run it? Because produceIn explicitly switch thread of Flow, so it may be not enough time to dispatched value
In theory there is shouldn't be context switch if you run it from other Default thread, but even in this case it will be asyncronously redispatched
t
@gildor this was exactly the code I wrapped in a
runBlocking { }
call and put in in a unit test
g
Exactly, runBlocking uses current thread, GlobalScope will use Default dispatcher, so you have thread switch there, so you cannot get update immidately
t
I get it now, appreciate your explanation. I have a
ConflatedBroadcastChannel
as a flow in my code. In a unit test I want to check the values of the flow, so I convert the flow to a channel using
produceIn
so I could use
poll()
. I'm now using
receive()
which does do what I want.
g
Yes, you need suspend
receive()
for this
I convert the flow to a channel using
produceIn
so I could use
poll()
But why do you need channel for this? You can just use suspend method
single()
to get 1 value from Flow
t
@gildor the flow has more than one value so I need to check it multiple times throughout the unit test. As I understand,
single()
requires the flow to send one value and be closed or else it won't return. So that's why I'm using `poll()`/`receive()` for this, because I need to check the value (multiple times) without closing the flow. If you know a better approach, please let me know because I might be missing something obvious.
g
I see what you mean
maybe than you could just convert all emits to list and assert it?
t
@gildor I’m not sure how, as far as I know Flow.
toList()
won’t work either because it requires the flow to be closed or it won’t return.
g
yes it’s true. It’s possible to cover such cases, but probably we need some sort testing facilities