I am trying to unit test a ViewModel where I am updating the value of a MutableStateFlow, but the thing is that when I try to test the Success State it gives me an error because the State remains as Idle, which is the initialization value. I am using Turbine to get the values since it is recommended, here my code
ViewModel code:
class HomeScreenViewModel @Inject constructor(private val getUserByPersonaNameUseCase: GetUserByPersonaNameUseCase) :
ViewModel() {
private var _state = MutableStateFlow<State>(State.Idle)
val state = _state
suspend fun getUserByName(name: String, event: Event) = viewModelScope.launch {
when (event) {
Event.SearchPlayerByPersonaName -> {
val result = getUserByPersonaNameUseCase.getUsersByPersonaName(name)
_state.value = if (result.isNotEmpty()) {
State.Success(result)
} else {
State.Error("Something went wrong")
}
}
}
}
}
ViewModelTest code:
@ExperimentalCoroutinesApi
class HomeScreenViewModelTest {
lateinit var sut: HomeScreenViewModel
lateinit var getUserByPersonaNameUseCase: GetUserByPersonaNameUseCase
val fakeList = listOf(
PlayerByPersonaName("player1", 1),
PlayerByPersonaName("player2", 2),
PlayerByPersonaName("player3", 3)
)
@Before
fun setUp() {
getUserByPersonaNameUseCase = mockk<GetUserByPersonaNameUseCase>()
sut = HomeScreenViewModel(getUserByPersonaNameUseCase)
}
@Test
fun `Given that getUserName is called with a name and the event is SearchPlayerByName, then the state is success `() =
runBlocking {
Dispatchers.setMain(Dispatchers.IO)
//Given
coEvery { getUserByPersonaNameUseCase.getUsersByPersonaName("atila") } returns fakeList
sut.state.test {
//When
sut.getUserByName("atila", Event.SearchPlayerByPersonaName)
//Then
val result = awaitItem()
assertTrue(result is State.Success)
}
}
}
Make sure that you call getUserByPersonaNameUseCase by :
You not calling it correctly since you not using the TestDispatcher.
Make sure that you pass the Dispatchers.IO to viewModelScope :