Imaginez le scénario de test autonome suivant
@Test
fun `stateFlow in GlobalScope`() = runBlockingTest {
suspend fun makeHeavyRequest(): String {
return "heavy result"
}
val flow1 = flowOf(Unit)
.map { makeHeavyRequest() }
.onEach { logThread("1: before flowOn") }
.flowOn(testDispatcher)
.stateIn(GlobalScope, SharingStarted.Lazily, "init state")
val flow2 = flowOf(Unit)
.map { makeHeavyRequest() }
.onEach { logThread("2: before flowOn") }
.flowOn(testDispatcher)
.stateIn(GlobalScope, SharingStarted.Lazily, "init state")
.onEach { logThread("2: after stateIn") }
val flow3 = flowOf(Unit)
.map { makeHeavyRequest() }
.onEach { logThread("3: before flowOn") }
.flowOn(testDispatcher)
.onEach { logThread("3: after flowOn") }
.stateIn(GlobalScope, SharingStarted.Lazily, "init state")
flow1.test {
assertEquals("heavy result", expectItem())
cancelAndIgnoreRemainingEvents()
}
flow2.test {
assertEquals("heavy result", expectItem())
cancelAndIgnoreRemainingEvents()
}
flow3.test {
assertEquals("heavy result", expectItem())
cancelAndIgnoreRemainingEvents()
}
}
L'effet de son exécution sera :
Thread (1: before flowOn): Thread[main @coroutine#2,5,main]
Thread (2: before flowOn): Thread[main @coroutine#3,5,main]
Thread (2: after stateIn): Thread[main @coroutine#6,5,main]
Thread (3: before flowOn): Thread[DefaultDispatcher-worker-1 @coroutine#8,5,main]
Thread (3: after flowOn): Thread[DefaultDispatcher-worker-1 @coroutine#4,5,main]
org.opentest4j.AssertionFailedError:
Expected :heavy result
Actual :init state
Sur flow3
placer le onEach
entre flowOn
y stateIn
change complètement le répartiteur et gâche le résultat. Pourquoi cela ?