Kotlin的Turbine:完整指南与示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Kotlin的Turbine:Flow测试完整指南

\n\n

1. 什么是Turbine及其用途

\n

Turbine库是一个用于测试Kotlin语言中协程数据流(Flow)的现代工具。由Cash App公司开发,Turbine解决了编写异步代码单元测试时最棘手的问题之一:验证Flow的值发射、错误处理和流完成状态的复杂性。与使用kotlinx-coroutines-test手动收集元素的标准方法不同,Turbine提供了声明式且直观的API,使测试更具可读性和可靠性。

\n\n

Turbine有什么用途?假设您正在编写一个ViewModel,它订阅仓库并将数据转换为UI状态。没有Turbine,您需要手动创建收集器、管理Job并同步协程。Turbine自动化了这一过程:它创建一个虚拟协程,将所有发射值收集到“涡轮”(因此得名),然后允许您按顺序检查每个值,忽略不重要的中间状态。这在测试类似BehaviourSubject的流时特别有用,因为只有最终状态才重要。

\n\n

该库的主要功能包括:按严格顺序检查发射值、使用skip()忽略中间值、通过awaitError()测试错误、通过awaitComplete()检查流完成,以及支持通道(Channel)和StateFlow。Turbine可与任何测试框架(JUnit、Kotest、Spek)集成,无需额外配置——只需添加依赖并使用testScope即可。

\n\n

2. 安装

\n

要在您的项目中使用Turbine,请在build.gradle.kts(或build.gradle)文件中添加以下依赖:

\n\n
// build.gradle.kts\ndependencies {\n    // 对于JVM项目\n    testImplementation("app.cash.turbine:turbine:1.1.0")\n    \n    // 如果您使用kotlinx-coroutines-test(推荐)\n    testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0")\n}\n\n// 对于Android项目(在android块中)\nandroid {\n    testOptions {\n        unitTests.isReturnDefaultValues = true\n    }\n}\n
\n\n

如果您使用Maven:

\n
<dependency>\n    <groupId>app.cash.turbine</groupId>\n    <artifactId>turbine</artifactId>\n    <version>1.1.0</version>\n    <scope>test</scope>\n</dependency>\n
\n\n

最低要求:Kotlin 1.9+,kotlinx-coroutines 1.8+。该库支持JVM、Android、JS和Native(通过Kotlin Multiplatform)。

\n\n

3. 快速入门

\n

让我们看一个最简单的例子:测试一个发射三个数字的Flow。

\n\n
import app.cash.turbine.test\nimport kotlinx.coroutines.flow.flowOf\nimport kotlinx.coroutines.test.runTest\nimport org.junit.Test\n\nclass SimpleTurbineTest {\n\n    @Test\n    fun `test flow emits three values`() = runTest {\n        val flow = flowOf(1, 2, 3)\n\n        flow.test {\n            // awaitItem()等待下一次发射并返回它\n            assertEquals(1, awaitItem())\n            assertEquals(2, awaitItem())\n            assertEquals(3, awaitItem())\n\n            // awaitComplete()检查流是否无错误完成\n            awaitComplete()\n        }\n    }\n}\n
\n\n

运行此测试——它将成功通过。请注意:test是一个挂起函数,它在单独的协程中启动流的收集。所有awaitItem()调用都会阻塞当前协程,直到下一个元素出现。如果流提前完成,测试将失败并抛出

推荐