myanmarking
05/21/2020, 9:58 AM@Test
fun `flow test`() = runBlockingTest{
Assert.assertEquals(
flow<Int>{
throw IllegalStateException()
}
.map { 1 }
.onCompletion { 2 }
.toList(),
listOf(2)
)
}
@Test
fun `flow test2`() = runBlockingTest{
Assert.assertEquals(
flow<Int>{
throw IllegalStateException()
}
.catch { }
.map { 1 }
.onCompletion { if(it != null) emit(2) }
.toList(),
listOf<Int>()
)
}
The first test crashes, the second test passes. So in what scenario does onComplete emits any exception other than cancellation ?julian
05/23/2020, 3:06 AMonCompletion
docs, onCompletion
doesn't emit an exception. The docs are just saying that the upstream exception (failure) gets passed as the cause
argument of the action
(lambda) argument that you provide to onCompletion
.onCompletion
behaves like finally
, so the first test still crashes even with onCompletion
applied. Furthermore, flow expects action
to return Unit
. So it doesn't matter that you have 2
in the lambda: { 2 }
. That has no effect. You'd need to emit
to have an effect.map
to 1
because you emit
nothing in the catch
lambda. In other words, the flow to this point is empty. So nothing to map. And 2
isn't emitted because the value of it
in the onCompletion
action
lambda is the upstream exception: if(it != null) emit(2) }
. The upstream exception isn't null, so emit(2)
isn't executed. So the list is empty. So the test passes.