Shashank
11/05/2023, 9:04 PM(isLoading=false…)
while testing. Any ideas how to receive both the states? Code in thread.class TestingViewModel : ViewModel() {
data class ViewState(
val isLoading: Boolean = false,
val data: String? = null,
)
private val _state: MutableStateFlow<ViewState> = MutableStateFlow(ViewState())
val state: StateFlow<ViewState> = _state.asStateFlow()
init {
_state.value = state.value.copy(isLoading = true)
_state.value = state.value.copy(isLoading = false, data = "hello!")
}
}
@Test
fun test() = runTest {
val vm = TestingViewModel()
vm.state.test {
println(awaitItem())
println(awaitItem())
}
}
jw
11/05/2023, 9:26 PMShashank
11/05/2023, 9:27 PMjw
11/05/2023, 9:29 PMShashank
11/05/2023, 9:30 PMjw
11/05/2023, 10:22 PMstreetsofboston
11/05/2023, 10:23 PMShashank
11/05/2023, 10:31 PMYou should test, assert, the end-state, given a start-stateSo all the VM tests should just assert the last state? And never a transition of states?
If your view model produces two states or fifty or just one in init then from the outside it will always appear as only oneWhat if there is an actual delay in the init block? Then I will receive both events To both: What I am trying to get at is that I want my test to be like: “On VM init, a load state is shown and then the data is presented”. But the conflation messes it up and I need to be wary of that. I am curious how you guys ever faced this and how you handled it? Or maybe I am testing the VM in a wrong way like Anton said and I should just be concerned with the final state.
jw
11/05/2023, 10:50 PMChris Fillmore
11/05/2023, 11:03 PMCasey Brooks
11/05/2023, 11:19 PMDmitry Khalanskiy [JB]
11/06/2023, 9:19 AMShashank
11/06/2023, 9:40 AM_state.value = state.value.copy(isLoading = true)
val data = repo.getUser() //suspend function
_state.value = state.value.copy(isLoading = false, data = data)
So the UI will see 2 states, one for loading and then the data state.Dmitry Khalanskiy [JB]
11/06/2023, 9:45 AMsuspend fun getUser(): User {
delay(20.milleseconds) // a network call
return createFakeUser()
}
Shashank
11/06/2023, 9:45 AMDmitry Khalanskiy [JB]
11/06/2023, 9:46 AMShashank
11/06/2023, 9:48 AMDmitry Khalanskiy [JB]
11/06/2023, 9:51 AMrunTest
will automatically skip delays (except in code forked off to other dispatchers, like <http://Dispatchers.IO|Dispatchers.IO>
or custom thread pools), so you can even write delay(400.hours)
without causing your tests to slow down or become non-deterministic.Shashank
11/06/2023, 9:51 AM