Imagine I have a `suspend` function that feeds a `...
# coroutines
d
Imagine I have a
suspend
function that feeds a
StateFlow
with one or two different values, in quick succession. How would I test this with Coroutines 1.6? Issue is that during the test I only see the second emitted value and the first is already gone. I tried different things using different dispatches, but nothing worked out unfortunately.
d
Hi! You could try collecting the
StateFlow
in an
UnconfinedTestDispatcher
. This will work unless the emissions themselves happen in an unconfined dispatcher. However, could you share why you set
SharedFlow
to two values in quick succession? In production, the first value will typically be lost as well, because
SharedFlow
conflates values. If you rely on both elements being received in production, this is very tricky to actually ensure.
d
It’s basically a network follows cache-response scenario. The disk is quickly read and emitted, the network call could take up to 20 seconds. In my test of course I don’t have such delays, but still want to see that both, the cached and the real value are emitted in proper order.
Hrm… this blocks for 60s and then bails out, dammit, this API: https://gist.github.com/realdadfish/25cb4d950cec6bfd6f6626cb32af1911
(This uses FlowTurbine for collecting / asserting)
d
In my test of course I don’t have such delays
The recommended solution is to mock the network call with
delay(20.seconds)
. In the test framework, delays are performed using a virtual source of time. So, in fact, the delay will finish instantly, but the test will "think" that 20 seconds passed.
d
Ah ok, sounds reasonable, will try that!
(I used a
CompletableDeferred
solution for this, which did not work)
Many thanks, this worked like a charm! I updated the gist accordingly and made it a bit simpler even: https://gist.github.com/realdadfish/25cb4d950cec6bfd6f6626cb32af1911
c
Turbine makes testing Flows much nicer https://github.com/cashapp/turbine