我有一个视图模型,它接受一个初始的ViewState
对象,并有一个可公开访问的state
变量,可以收集。
class MyViewModel<ViewState>(initialState: ViewState) : ViewModel() {
val state: StateFlow<ViewState> = MutableStateFlow(initialState)
val errorFlow: SharedFlow<String> = MutableSharedFlow()
init {
performNetworkCall()
}
private fun performNetworkCall() = viewModelScope.launch {
Network.makeCall(
"/someEndpoint",
onSuccess = {
(state as MutableStateFlow).tryEmit(<some new state>)
},
onError = {
(errorFlow as MutableSharedFlow).tryEmit("network failure")
}
)
}
}
当从片段中观察这个状态时,我可以看到初始状态(例如加载),并且我收集网络调用成功完成时的变化(例如,到加载状态)
然而,我不知道如何观察我的ViewModelUnitTest
的这种发射。我使用kotlin涡轮机测试我的状态和共享流量的排放,但我只能观察到调用viewModel.state.test
或viewModel.errorFlow.test
后发生的排放。
由于我不能在ViewModel初始化之前引用viewModel.state
或viewModel.errorFlow
,我如何编写一个测试来验证我的初始化逻辑正确执行并根据Network.makeCall
的模拟行为发出预期的结果-无论是state
的新发射还是errorFlow
的发射?
由于您的网络类在视图模型中没有任何引用,因此不可能模拟/伪造Network
类的行为。因此,为Network
创建一个引用。为了捕获init
块中发生的事情,您可以在测试类中延迟初始化视图模型。这里描述的是第二种方式。大致上,您的类看起来类似于:
class MyViewModel<ViewState>(
initialState: ViewState,
network: Network
) : ViewModel() {
val state: StateFlow<ViewState> = MutableStateFlow(initialState)
val errorFlow: SharedFlow<String> = MutableSharedFlow()
init {
performNetworkCall()
}
private fun performNetworkCall() = viewModelScope.launch {
network.makeCall(
"/someEndpoint",
onSuccess = {
(state as MutableStateFlow).tryEmit(<some new state>)
},
onError = {
(errorFlow as MutableSharedFlow).tryEmit("network failure")
}
)
}
}
@ExperimentalCoroutinesApi
class MyViewModelTest {
@get:Rule
var coroutinesTestRule = CoroutinesTestRule()
val viewModel by lazy { MyViewModel(/*pass arguments*/) }
}
CoroutineTestRule
可以在这里找到。