【发布时间】:2020-06-27 23:52:32
【问题描述】:
我有一个 ViewModel 与一个用例对话并得到一个流回,即Flow<MyResult>。我想对我的 ViewModel 进行单元测试。我是使用流程的新手。需要帮助。这是下面的视图模型 -
class MyViewModel(private val handle: SavedStateHandle, private val useCase: MyUseCase) : ViewModel() {
private val viewState = MyViewState()
fun onOptionsSelected() =
useCase.getListOfChocolates(MyAction.GetChocolateList).map {
when (it) {
is MyResult.Loading -> viewState.copy(loading = true)
is MyResult.ChocolateList -> viewState.copy(loading = false, data = it.choclateList)
is MyResult.Error -> viewState.copy(loading = false, error = "Error")
}
}.asLiveData(Dispatchers.Default + viewModelScope.coroutineContext)
MyViewState 看起来像这样 -
data class MyViewState(
val loading: Boolean = false,
val data: List<ChocolateModel> = emptyList(),
val error: String? = null
)
单元测试如下所示。断言失败总是不知道我在那里做错了什么。
class MyViewModelTest {
@get:Rule
val instantExecutorRule = InstantTaskExecutorRule()
private val mainThreadSurrogate = newSingleThreadContext("UI thread")
private lateinit var myViewModel: MyViewModel
@Mock
private lateinit var useCase: MyUseCase
@Mock
private lateinit var handle: SavedStateHandle
@Mock
private lateinit var chocolateList: List<ChocolateModel>
private lateinit var viewState: MyViewState
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
Dispatchers.setMain(mainThreadSurrogate)
viewState = MyViewState()
myViewModel = MyViewModel(handle, useCase)
}
@After
fun tearDown() {
Dispatchers.resetMain() // reset main dispatcher to the original Main dispatcher
mainThreadSurrogate.close()
}
@Test
fun onOptionsSelected() {
runBlocking {
val flow = flow {
emit(MyResult.Loading)
emit(MyResult.ChocolateList(chocolateList))
}
Mockito.`when`(useCase.getListOfChocolates(MyAction.GetChocolateList)).thenReturn(flow)
myViewModel.onOptionsSelected().observeForever {}
viewState.copy(loading = true)
assertEquals(viewState.loading, true)
viewState.copy(loading = false, data = chocolateList)
assertEquals(viewState.data.isEmpty(), false)
assertEquals(viewState.loading, true)
}
}
}
【问题讨论】:
-
这里需要测试什么?需要测试的确切场景是什么?首先用文字描述测试。
-
@Code-Apprentice - 我需要测试视图模型是否从用例接收到 Flow
并在其上构建视图状态并提供给观察者 -
@Maria 哪种方法有效?
-
视图模型中的onOptionsSelected()
-
@IgorGanapolsky 我的 Fragment 观察到一个 livedata,因此我需要为 viewModel 中的流做 asLiveData
标签: android kotlin junit4 kotlin-coroutines android-mvvm