Sam
Sam

Reputation: 6395

how to test stateFlows when emitting multiple items

I'm trying to write an unit test for following method in ViewModel Class, but test is always failing on assert items,

expected:<UiState(showLoading=true,...

Actual :UiState(showLoading=false...,

not sure why test is not waiting for item to emit.

 class TestViewModel(private val signInUseCase: SignInUseCase) {
        
        
            private val mutableUiState = MutableStateFlow(AuthContract.UiState())
            val uiState: StateFlow<tAuthContract.UiState> = mutableUiState.asStateFlow()
        
            fun simulateAPICall() {
                viewModelScope.launch {
        
                    mutableUiState.update(showLoading = true)
                    delay(100)
                    //signInUseCase.invoke("username","password")
        
                    mutableUiState.update(
                        showLoading = false,
                    )
                }
            }
        
        }
        //----------------
        class TestViewModelTest {
        
            @MockK
            private lateinit var signInUseCase: SignInUseCase
        
            private lateinit var viewModel: TestViewModel
        
            @get:Rule
            val coroutineTestRule = CoroutineTestRule(UnconfinedTestDispatcher())
        
            @Before
            fun setup() {
                MockKAnnotations.init(this)
                val context: Context = mockk(relaxed = true)
        
                viewModel = TestViewModel(
                    signInUseCase
                )
            }
        
            @Test
            fun `test SignInFlow`() = runTest {
                viewModel.uiState.test {
                    viewModel.simulateAPICall()
                
        
                val expectedLoading = AuthContract.UiState(showLoading = true)
                Assert.assertEquals(expectedLoading, awaitItem())
        
                val expectedSignInSuccess = AuthContract.UiState(
                    showLoading = false,
                )
                Assert.assertEquals(expectedSignInSuccess, awaitItem())
            }
           }
        
        }
        //----------------
        
        @OptIn(ExperimentalCoroutinesApi::class)
        class CoroutineTestRule(private val testDispatcher: TestDispatcher = StandardTestDispatcher()) :
            TestWatcher() {
        
            override fun starting(description: Description) {
                super.starting(description)
                Dispatchers.setMain(testDispatcher)
            }
        
            override fun finished(description: Description) {
                super.finished(description)
                Dispatchers.resetMain()
            }
        }
    
    kotlinx-coroutines-test= 1.6.4
    mockkVersion= 1.13.5
    turbine="0.12.1"

Upvotes: 0

Views: 261

Answers (0)

Related Questions