Skip to content

Testing Library ‐ Turbine

Devrath edited this page Oct 26, 2023 · 4 revisions

github-header-image

Scenario

  • When we are testing the states in a view model or in any other place, There comes a requirement where we need to test the order in which the states are triggered.
  • Say for example, loading started state is triggered ----> then ---> API call is successful is triggered ----> then ---> loading successful state is triggered
  • Now when we test the state reference, only it holds the last state when testing the states.
  • But we might need to check the order of the states triggered and also whether other states are triggered.
  • In such a scenario, we can use turbine.

Library

Code

ProfileViewModel.kt

class ProfileViewModel(
    private val repository: UserRepository,
    savedStateHandle: SavedStateHandle
): ViewModel() {

    private val userId = savedStateHandle.get<String>("userId")

    private val _state = MutableStateFlow(ProfileState())
    val state = _state.asStateFlow()

    fun loadProfile() {
        viewModelScope.launch {
            userId?.let { id ->
                _state.update { it.copy(isLoading = true) }

                val result = repository.getProfile(id)

                _state.update { it.copy(
                    profile = result.getOrNull(),
                    errorMessage = result.exceptionOrNull()?.message,
                    isLoading = false
                ) }
            }
        }
    }
}

TestCase

@Test
fun `Test loading state updates`() = runTest{
        viewModel.state.test {
            // This will suspend the test case until there is emission of first item
            val emission1 = awaitItem()
            assertThat(emission1.isLoading).isFalse()
            // Perform next action in the view-model
            viewModel.loadProfile()
            // Check the next emission -- Until the next emission the test block is blocked
            val emission2 = awaitItem()
            assertThat(emission2.isLoading).isTrue()
            // Check the next emission which is final emission
            val emission3 = awaitItem()
            assertThat(emission3.isLoading).isFalse()
        }
}