我正在尝试对 ViewModel 进行单元测试,在其中更新 MutableStateFlow 的值,但问题是,当我尝试测试成功状态时,它给了我一个错误,因为状态保持为空闲状态,这是初始化值。我正在使用 Turbine 来获取值,因为这是推荐的,这里是我的代码
ViewModel代码:
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")
}
}
}
}
}
ViewModel测试代码:
@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)
}
}
}
确保您通过以下方式调用 getUserByPersonaNameUseCase :
coVerify { getUserByPersonaNameUseCase.getUsersByPersonaName("atila") }
您没有正确调用它,因为您没有使用 TestDispatcher。
确保您通过了 Dispatchers.IO :
suspend fun getUserByName(name: String, event: Event) = viewModelScope.launch(Dispatchers.IO) {
when (event) {
Event.SearchPlayerByPersonaName -> {
val result = getUserByPersonaNameUseCase.getUsersByPersonaName(name)
_state.value = if (result.isNotEmpty()) {
State.Success(result)
} else {
State.Error("Something went wrong")
}
}
}
}