Rob*_*kus 9 junit android kotlin android-jetpack-compose
我已经实现了公开 ComposeState<T>实例的 Android 视图模型。例如,查看模型实现:
class MyViewModel<S> {
private val _viewState: MutableState<S> = mutableStateOf(initialState)
val viewState: State<S> = _viewState
...
protected fun setState(newState: S) {
_viewState.value = newState
}
}
Run Code Online (Sandbox Code Playgroud)
我想在单元测试中测试它将设置什么值/状态。只是我想要实现的目标的一个简短示例:
class MyViewModelTest {
@Test
fun `when view model initialized then should emit initial state first`() {
val viewModel = MyViewModel()
assertEquals(InitialState(), viewModel.viewState.value)
}
@Test
fun `when view model interacted then should emit result state`() {
val viewModel = MyViewModel()
val expectedState = NewState()
viewModel.setState(expectedState)
assertEquals(expectedState, viewModel.viewState.value)
}
}
Run Code Online (Sandbox Code Playgroud)
可以测试吗State<T>?如果将状态值存储在视图模型端,你们如何进行单元测试?
对于我的特定用例,我使用协程和单向数据流,但通过mutableStateOf. 正在寻找单元测试的初始状态+事件的影响,就像你的情况一样。
class MyViewModel(
// For injecting test dispatcher
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
) : ViewModel() {
// State exposed via delegate
var state by mutableStateOf(State.Show())
private set
fun onEvent(event: Event) {
when (event) {
is Event.Greet -> greet(event)
else -> TODO("Other Stuff")
}
}
private fun greet(greet: Event.Greet) {
viewModelScope.launch(dispatcher) {
// Do some, ya know, API stuff!
state = State.Show("Hello ${greet.name}")
}
}
}
Run Code Online (Sandbox Code Playgroud)
state通过委托和私有设置器公开。初始值为Show("Hello")。我们还可以直接使用导入设置更新:
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
Run Code Online (Sandbox Code Playgroud)
调度程序的注入对于控制进程至关重要。
// Encapsulates possible states
sealed class State {
// Data class calculates equality from the constructor
// aiding with assertEquals
data class Show(
val greeting: String = "Hello"
) : State()
}
// ... and possible Events
sealed class Event {
data class Greet(val name: String) : Event()
}
Run Code Online (Sandbox Code Playgroud)
@ExperimentalCoroutinesApi
@RunWith(MockitoJUnitRunner::class)
class MyViewModelTest {
val dispatcher = StandardTestDispatcher()
@Test
fun `viewModel shows initial state`() = runTest {
val vm = MyViewModel(dispatcher)
val expectedState = State.Show()
// Get the initial state
val state = vm.state
assertEquals(expectedState, state)
}
@Test
fun `viewModel shows updated state`() = runTest {
val vm = MyViewModel(dispatcher)
val expectedState = State.Show("Hello Robertus")
// Trigger an event
vm.onEvent(Event.Greet("Robertus"))
// Await the change
dispatcher.scheduler.advanceUntilIdle()
// Get the state
val state = vm.state
assertEquals(expectedState, state)
}
}
Run Code Online (Sandbox Code Playgroud)
让val dispatcher = StandardTestDispatcher()我们传入一个我们可以控制的调度程序来等待协程。我们在测试中以及需要等待它们运行和更新状态时将其传递给 ViewModel。
注意:测试在表达式内
= runTest { }。
对于第一个测试,viewModel shows initial state,我们得到初始化时使用的初始值mutableStatOf。
在第二个测试中,我们通过在传递和获取之间viewModel shows updated state调用来等待协程完成(调度程序空闲)。dispatcher.scheduler.advanceUntilIdle()Eventstate
| 归档时间: |
|
| 查看次数: |
4030 次 |
| 最近记录: |