0

when viewmodel init, if user is already logged in, the livedata _resultEvent.value will change twice

class LoginViewModel @Inject constructor( private val loginUseCase: LoginUser, private val getUserIfLogged: GetUserIfLogged ): ViewModel() {

private val _resultEvent = MutableLiveData<Event<AuthEvents<String>>>()
val resultEvent: LiveData<Event<AuthEvents<String>>> = _resultEvent

init {
    viewModelScope.launch {
        val userID = getUserIfLogged.invoke()
        if (userID != null){
            _resultEvent.value =
                Event(AuthEvents.SuccessSnackBar(message = "Welcome"))
            delay(1500)
            _resultEvent.value =
                Event(AuthEvents.NavigateToMainAuthenticated(userID))
        }
    }
    // other things....
}

when i write a test for this using the LiveDataTestUtil function by Google to observe livedata, i got a lot of errors

java.util.concurrent.TimeoutException: LiveData value was never set.

so i write a test that "works", but i am not sure that is the right way to do this kind of test using advanceTimeBy(), because if i don't know when the live data will change his value, or how much values will be emitted, i will not be able to do the test using this method.

// 
@Before fun setUp(){ 
Dispatchers.setMain(dispatcher) // StandardTestDispatcher() 
coEvery { getUserIfLogged.invoke() } returns null 
viewModel = LoginViewModel(loginUser, getUserIfLogged) 
}

@After 
fun tearDown(){ 
Dispatchers.resetMain() 
}

@Test fun if user is logged, init should emit a SnackBar and Navigate events() = runTest{ 

// Given 
coEvery { getUserIfLogged.invoke() } returns "someUserID"

// When (viewModel starts)
advanceTimeBy(1)
val result1 = viewModel.resultEvent.getOrAwaitValue()
advanceUntilIdle()
val result2 = viewModel.resultEvent.getOrAwaitValue()

// Then
coVerify { getUserIfLogged.invoke() }
assertTrue(result1?.getIfIsNotHandled() is AuthEvents.SuccessSnackBar)
assertTrue(result2?.getIfIsNotHandled() is AuthEvents.NavigateToMainAuthenticated)

}

please give me a feedback, is this test OK? or there are another better ways?

0 Answers0