### 第1章:搭建JUnit5与Mockito测试环境
#### 1.1 环境搭建的核心目标
在开始编写协程Worker的单元测试之前,必须搭建一套稳定、兼容的测试基础设施。本章将引导你完成以下核心任务:
- 在Kotlin/Gradle项目中添加JUnit5、Mockito及协程测试依赖。
- 配置`kotlin-test`插件,确保测试框架能够正确发现并执行协程相关的测试用例。
- 启用协程测试依赖库,使测试代码能够控制协程的调度、时间与生命周期。
---
#### 1.2 技术组件与版本兼容性
下表列出本章会涉及的核心依赖及其推荐版本。版本选择遵循 **2024年下半年主流稳定组合**,兼顾功能完整性与社区支持周期。
| 组件 | 依赖坐标 | 推荐版本 | 说明 |
|:--|:--|:--|:--|
| JUnit5 (Jupiter) | `org.junit.jupiter:junit-jupiter` | 5.10.2 | 包含引擎、API与参数化测试 |
| Mockito | `org.mockito:mockito-core` | 5.11.0 | 核心mock框架 |
| Mockito Kotlin | `org.mockito.kotlin:mockito-kotlin` | 5.2.1 | 提供Kotlin友好的DSL支持 |
| Kotlin协程测试 | `org.jetbrains.kotlinx:kotlinx-coroutines-test` | 1.8.0 | 提供`runTest`、`TestDispatcher`等 |
| Kotlin测试 | `org.jetbrains.kotlin:kotlin-test` | 1.9.22 | 提供`@Test`、断言等基础注解 |
> **版本兼容性提示**:`kotlinx-coroutines-test` 1.8.0 要求 Kotlin 1.9.0+,且与 `kotlin-test` 1.9.22 完全兼容。若使用低版本Kotlin,请同步降级协程测试库。
---
#### 1.3 完整Gradle依赖配置(build.gradle.kts)
以下是一个Kotlin JVM项目的完整测试依赖配置。假设项目已应用`org.jetbrains.kotlin.jvm`插件,并配置了Maven Central仓库。
**步骤1:启用JUnit5测试引擎**
// build.gradle.kts
plugins {
kotlin("jvm") version "1.9.22"
}
repositories {
mavenCentral()
}
dependencies {
// 核心测试框架
testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
// Mockito + Kotlin扩展
testImplementation("org.mockito:mockito-core:5.11.0")
testImplementation("org.mockito.kotlin:mockito-kotlin:5.2.1")
// Kotlin协程测试基础库
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0")
// Kotlin标准测试注解与断言
testImplementation(kotlin("test"))
}
// 明确指示使用JUnit5平台
tasks.test {
useJUnitPlatform()
}
**步骤2:配置kotlin-test插件(可选但推荐)**
如果你需要`@Test`、`@BeforeEach`、`@AfterEach`等注解的Kotlin原生封装,建议在`build.gradle.kts`中添加以下配置:
kotlin {
sourceSets {
val test by getting {
dependencies {
// 确保kotlin-test与JUnit5桥接
implementation(kotlin("test-junit5"))
}
}
}
}
> 此步骤并非强制,因为`kotlin("test-junit5")`提供的注解与`org.junit.jupiter.api`高度重叠。对于纯JUnit5项目,直接使用原版Jupiter注解更直观。
**步骤3:验证依赖是否完整下载**
执行以下Gradle命令,确认所有测试依赖已解析且无版本冲突:
./gradlew dependencies --configuration testRuntimeClasspath
预期输出中应包含`junit-jupiter`、`mockito-core`、`mockito-kotlin`、`kotlinx-coroutines-test`等关键库,且版本号与你配置的一致。
---
#### 1.4 协程测试依赖核心原理
`kotlinx-coroutines-test` 库提供了三大核心能力,它们是编写协程Worker单元测试的基石:
1. **`runTest`**:一个挂起函数,将测试代码包装在可控的协程作用域内,自动处理协程的启动与取消。
2. **`StandardTestDispatcher`**:一个虚拟时间调度器,允许测试代码按需推进虚拟时间,而无需等待真实挂起。
3. **`TestScope`**:一个顶层协程作用域,与`runTest`配合使用,提供`backgroundScope`用于管理后台协程。
下图展示了测试环境各组件如何协作,支撑协程Worker的单元测试:
---
#### 1.5 验证环境:第一个协程测试
完成依赖配置后,编写一个极简测试用例,验证环境是否正常工作。
// src/test/kotlin/com/example/EnvironmentCheckTest.kt
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test
class EnvironmentCheckTest {
@Test
fun `验证 runTest 可以正确执行协程测试`() = runTest {
// 当环境配置正确时,这段代码应无异常通过
val result = kotlinx.coroutines.delay(10L) // 虚拟时间,不会真实等待
assert(true) { "环境验证通过" }
}
}
执行测试命令:
./gradlew test --tests "*EnvironmentCheckTest*"
若输出包含`BUILD SUCCESSFUL`,则说明JUnit5、kotlin-test与协程测试依赖已正确集成。若出现`ClassNotFoundException`或`MethodNotFoundException`,请检查依赖版本冲突(常见于kotlinx-coroutines-test与kotlin版本不匹配)。
---
#### 1.6 常见错误与排查
| 错误现象 | 可能原因 | 解决方案 |
|:--|:--|:--|
| `java.lang.NoClassDefFoundError: kotlinx/coroutines/test/TestDispatcher` | `kotlinx-coroutines-test` 未添加或版本不兼容 | 检查`testImplementation`声明;确认Kotlin版本≥1.9.0 |
| `org.opentest4j.AssertionFailedError: expected: true but was: false` | 协程内部断言未生效 | 确认`runTest`作用域内使用JUnit5的`assert` |
| `kotlinx.coroutines.test.UncompletedCoroutinesError` | 测试结束后仍有未完成协程 | 在`runTest`中确保所有子协程完成或取消 |
| `kotlin.test.Test` 与 `org.junit.jupiter.api.Test` 冲突 | 同时引入了`kotlin-test`和JUnit5 | 仅保留`kotlin("test-junit5")`或纯Jupiter注解 |
---
#### 1.7 本章小结
通过本章配置,你已获得:
1. **完整的JUnit5测试引擎**,支持参数化测试、扩展模型。
2. **Mockito + Kotlin扩展**,能够对协程Worker中的依赖进行模拟。
3. **`kotlinx-coroutines-test`**,提供虚拟时间调度与协程作用域控制,是后续章节编写协程Worker单元测试的核心工具。
从下一章开始,我们将构建一个真实协程Worker并逐步为其编写健壮的单元测试。