观察ViewModel初始化时StateFlow的发射



我有一个视图模型,它接受一个初始的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.testviewModel.errorFlow.test后发生的排放。

由于我不能在ViewModel初始化之前引用viewModel.stateviewModel.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可以在这里找到。