I was trying to test an IO call which is made over a flow , simply returns me List of data .
but when testing and debugging I saw that when using flowOn(Dispatcher.IO)
it makes emitting of value on IO but collect remains on main thread .
My question is that how do i test this , i have mentioned the testing script i used but it was not working as from android developers documentation .
my view model function and variable
private val _isLoading = MutableStateFlow<Boolean>(false)
val isLoading :StateFlow<Boolean> = _isLoading.asStateFlow()
fun fetchDeviceInfo(){
currentJob?.cancel()
currentJob =viewModelScope.launch {
repository.fetchTrackerData()
.flowOn(Dispatchers.IO)// this is used to make emit on IO
.catch { e->
_isLoading.emit(false)
_isError.emit(true)
}
.collect{data->
withContext(Dispatchers.IO) {
when (data) {
is TrackerState.Error -> {
_isError.emit(true)
_isLoading.emit(false)
}
is TrackerState.Loading -> {
_isLoading.emit(true)
}
is TrackerState.Success -> {
_isError.emit(false)
_listData.emit(data.data)
_isLoading.emit(false)
}
}
}
}
}
}
this is my fakerepository that i am using to emit data on
suspend fun emit(value:TrackerState<List<DeviceInfo>>) = flow{
emit(value)
}
override suspend fun fetchTrackerData()=flow
this is my testing function, I didn`t use mockito here
@Test
fun `fetchDeviceInfo should update Loading`()= runTest {
viewModel.fetchDeviceInfo()//collector of flow
repository.emit(TrackerState.Loading())// our fake emitter
advanceUntilIdle()
assert(viewModel.isLoading.value)
}
i then tried adding advanceUntileIdle after seeing that collect itself is a suspend function so take time to setup
`@Test
fun `fetchDeviceInfo should update Loading`()= runTest {
viewModel.fetchDeviceInfo()//collector of flow
advanceUntilIdle()
repository.emit(TrackerState.Loading())// our fake emitter
advanceUntilIdle()
assert(viewModel.isLoading.value)
}
this fixed my issue hoowever I am wondering why do I use advanceUntilIdle() again?