I’m having some trouble to test some state changes in my viewModel using MutableSharedFlow. For example, I have this class
class SampleViewModel : ViewModel() {
private val interactions = Channel<Any>()
private val state = MutableSharedFlow<Any>(
onBufferOverflow = BufferOverflow.DROP_LATEST,
extraBufferCapacity = 1
)
init {
viewModelScope.launch {
interactions.receiveAsFlow().collect { action ->
processAction(action)
}
}
}
fun flow() = state.asSharedFlow()
fun handleActions(action: Any) {
viewModelScope.launch {
interactions.send(action)
}
}
suspend fun processAction(action: Any) {
state.emit("Show loading state")
// process something...
state.emit("Show success state")
}
}
I'm trying to test it using this method (already using version 1.6.1):
@Test
fun testHandleActions() = runTest {
val emissions = mutableListOf<Any>()
val job = launch(UnconfinedTestDispatcher(testScheduler)) {
viewModel.flow().collect {
emissions.add(it)
}
}
viewModel.handleActions("")
assertTrue(emissions[0] is String)
assertTrue(emissions[1] is String)
job.cancel()
}
If I test the viewmodel.processAction() it works like a charm. But if I try to test handleActions() I only receive the first emission and then it throws an IndexOutOfBoundsException
If I use the deprecated runBlockingTest, it works
@Test
fun testHandleActionsWithRunBlockingTest() = runBlockingTest {
val emissions = mutableListOf<Any>()
val job = launch {
viewModel.flow().toList(emissions)
}
viewModel.handleActions("")
job.cancel()
assertTrue(emissions[0] is String)
assertTrue(emissions[1] is String)
}
Did I miss something using runTest block?