I’ve a ViewModel that has a viewModelScope.launch{} on the init{}. I’m trying to run a test where I set Dispatchers.setMain(StandardTestDispatcher()) but the launch{} is running before I call advanceUntilIdle(). Why is that? Shouldn't it wait?
class TestViewModel : ViewModel() {
val state = MutableStateFlow("A")
init {
viewModelScope.launch {
state.update { "B" }
}
}
}
class TestViewModelTest {
private lateinit var viewModel: TestViewModel
@Before
fun setup() {
Dispatchers.setMain(StandardTestDispatcher())
viewModel = TestViewModel()
}
@Test
fun test() = runTest {
assert(viewModel.state.value == "A") // Fails, value is "B"
advanceUntilIdle()
assert(viewModel.state.value == "B")
}
}
As explained in the issue opened on coroutine's GitHub,
runTestautomatically runs all enqueued tasks. With this in mind, changing the test to this fix it: