jean
11/17/2022, 10:19 PMsuspend fun loadData(
scope: CoroutineScope,
state: MutableStateFlow<ViewState>,
) {
state.update {
it.copy(
data1 = it.data1.copy(status = AsyncDataStatus.LOADING),
data2 = it.data2.copy(status = AsyncDataStatus.LOADING),
data3 = it.data3.copy(status = AsyncDataStatus.LOADING),
)
}
scope.launch { loadData1FromRepository(state) }
scope.launch { loadData2FromRepository(state) }
scope.launch { loadData3FromRepository(state) }
}
private suspend fun loadData1(
state: MutableStateFlow<ViewState>
) = loadData1FromRepository().collect { result -> // this is a flow of 2 either values coming from a database and network
state.update { it.copy(data1 = newAsyncValue(result)) }
}
when running tests, I get a time out exception
state.test {
val loading = awaitItem()
assertEquals(
expected = initial.copy(
data1 = initial.data1.copy(status = AsyncDataStatus.LOADING),
data2 = initial.data2.copy(status = AsyncDataStatus.LOADING),
data3 = initial.data3.copy(status = AsyncDataStatus.LOADING),
),
actual = loading,
) // this passes correctly
val data1Loaded = awaitItem()
assertEquals(
expected = loading.copy(
data1 = initial.data1.copy(
status = AsyncDataStatus.SUCCESS,
data = someData1,
),
),
actual = data1Loaded,
) // here I get the time out
What am I supposed to do inorder to make the coroutines complete and return a value before the timeout?mkrussel
11/17/2022, 10:39 PMloadData function does not actual suspend, since it launches its async work and returns.
So either the function shouldn't be marked as suspend or it should wait for the launches to complete. The normal way to do that would be to call coroutineScope inside your suspend function instead of passing a scope to it.jean
11/18/2022, 8:21 PMsupervisorScope instead of coroutineScope since I don’t want children jobs cancelling each others if one fails.