1

I'm trying to unit test my ViewModel. It has a state which is of the type StateFlow.
When I call my useCase, I set the value of the state to Loading in the onStart block as follows:

@HiltViewModel
class MyViewModel @Inject constructor(private val myUseCase: MyUseCase) : ViewModel() {
    // ...
    private val _state: MutableStateFlow<MyState> = MutableStateFlow(MyState.Loading)
    val state = _state.asStateFlow()
    
    init {
       loadData()    
    }

    fun loadData() {
       viewModelScope.launch {
          myUseCase().onStart {
             _state.value = MyState.Loading    
          }.collect { data ->
             // ...
             _state.value = MyState.Data(data)
          }
       }
    }
    // ...
}

I'm trying to test that the first emitted value from the flow is the Loading state but my test fails and says expected Data not Loading.

Here is my test class:

class MyViewModelTest {
   private lateinit var viewModel: MyViewModel
   private lateinit var fakeUseCase: MyFakeUseCase

   @BeforeEach
    fun setup() {
        fakeUseCase = MyFakeUseCase()
        viewModel = MyViewModel(fakeUseCase)
    }

    @Test
    fun loadData_anyCriteria_stateIsLoadingOnStart() {
        runBlocking {
            // Act
            viewModel.loadData()
            val result = viewModel.state.first()

            // Assert
            Assertions.assertEquals(result, MyState.Loading)
        }
    }
}

Test result:

Expected :Data(bla bla bla)

Actual   :com.example....MyState$Loading@7b8233cd

How can I test the first value emitted from a StateFlow?

Mohamed Medhat
  • 761
  • 11
  • 16

0 Answers0