I was testing some Kotlin Flows according to what the document mentioned in this part.
I created a FakeRepository and a FakeViewModel like this:
class FakeRepository {
private val flow = MutableSharedFlow<Int>()
suspend fun emit(value: Int) = flow.emit(value)
val scores: Flow<Int> = flow
}
class FakeViewModel(private val repository: FakeRepository) : ViewModel() {
val score: StateFlow<Int> = repository.scores
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), 0)
fun initialize() {
viewModelScope.launch {
//delay(100)
repository.emit(1)
//delay(100)
repository.emit(2)
//delay(100)
repository.emit(3)
//delay(100)
}
}
}
I also created a test class to test this score flow like this:
@ExperimentalCoroutinesApi
class FakeViewModelTest {
/*
Replace real dispatchers with instances of TestDispatchers to ensure that all
code runs on the single test thread.
*/
@get:Rule
val mainDispatcherRule = MainDispatcherRule()
@Test
fun testFakeRepository() = runTest {
val fakeRepository = FakeRepository()
val viewModel = FakeViewModel(fakeRepository)
val items = mutableListOf<Int>()
val job = launch(StandardTestDispatcher()) {
viewModel.score.toList(items)
}
viewModel.initialize()
advanceUntilIdle()
MatcherAssert.assertThat(items.size, Matchers.equalTo(4))
job.cancel()
}
}
When I run the test, surprisingly, it fails and says that the list size is 1.
But after uncommenting the delays, the test will be passed.
Why the test behave like this? As the document mentioned here, TestDispatcher will skip delays.
Did I misunderstand something? How can I fix it?


