0Pricing
Jetpack Compose Academy · 课时

测试 ViewModel 与 Flow

使用测试调度器进行单元测试。

测试 ViewModel 与 Flow 是 CoddyKit 上的免费 Jetpack Compose Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Jetpack Compose Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Jetpack Compose Academy 课程共包含 4 节课。

本课时的部分内容尚未翻译,以英文显示。

Test Logic Without the UI

A ViewModel holds your screen logic, so you can test it directly with plain JUnit. No emulator or rendering needed, which makes these tests fast. ⚡

Arrange, Act, Assert

ViewModel tests follow a simple rhythm: create the ViewModel, call a function, then assert the new state. Keep each test focused on one behavior.

val vm = CounterViewModel()
vm.increment()
assertEquals(1, vm.count)

The Coroutine Challenge

Many ViewModels launch coroutines, which run on Dispatchers.Main. In tests there is no main looper, so you must swap in a test dispatcher instead.

StandardTestDispatcher

A StandardTestDispatcher gives you full control over coroutine timing. Tasks queue up and run only when you advance the virtual clock.

val dispatcher = StandardTestDispatcher()

Replace the Main Dispatcher

Use Dispatchers.setMain before each test to inject your test dispatcher, then call resetMain afterward to leave global state clean.

Dispatchers.setMain(dispatcher)

runTest

Wrap suspending test bodies in runTest. It provides a coroutine scope with a virtual clock so delays resolve instantly, not in real seconds.

@Test fun loads() = runTest {
    // suspend calls run here
}

Quick Check

Your ViewModel launches coroutines on the main dispatcher. What lets a unit test control their execution?

Advancing the Clock

With a StandardTestDispatcher, queued coroutines wait. Call advanceUntilIdle inside runTest to run them all, then check the final state.

advanceUntilIdle()
assertEquals(Loaded, vm.uiState.value)

Testing a StateFlow

ViewModels often expose a StateFlow. Its current snapshot lives in .value, so you can read and assert it directly after advancing the clock.

assertEquals(0, vm.count.value)

Collecting Flow Emissions

To capture a sequence of emissions, the Turbine library makes Flow testing easy with awaitItem, asserting each value as it arrives.

vm.events.test {
    assertEquals(Saved, awaitItem())
}

Fake Your Dependencies

Inject a fake repository that returns canned data. This keeps tests fast and lets you simulate success and error paths without a real network.

val vm = NewsViewModel(FakeRepo())

Clean Teardown

Always pair setMain with resetMain in your teardown. Leaving a test dispatcher installed can leak into and break other tests in the suite.

@After fun tearDown() {
    Dispatchers.resetMain()
}

Recap: ViewModels & Flows

Test logic without UI by swapping in a test dispatcher, running code in runTest, and asserting StateFlow values. Fast, focused, reliable tests. 🏁

常见问题解答

「测试 ViewModel 与 Flow」课时是免费的吗?

是的 — 「测试 ViewModel 与 Flow」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Jetpack Compose Academy 课程的其余内容,请升级到 CoddyKit PRO。 Jetpack Compose Academy 课程共包含 4 节课。

「测试 ViewModel 与 Flow」这节课中我会学到什么?

使用测试调度器进行单元测试。 你通过在浏览器中直接运行的动手代码来练习 Jetpack Compose Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Jetpack Compose Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Jetpack Compose Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「测试 ViewModel 与 Flow」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Jetpack Compose Academy 课中编写并运行代码吗?

能。每节 Jetpack Compose Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. createComposeRule 与查找器
  2. 断言与执行操作
  3. 语义与测试标签
  4. 测试 ViewModel 与 Flow
← 返回 Jetpack Compose Academy