### 第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的单元测试: 测试环境组件依赖关系 Gradle 项目(build.gradle.kts) 托管所有测试依赖与插件配置 JUnit5 测试引擎 junit-jupiter 5.10.2 提供 @Test / Assertions Mockito 模拟框架 mockito-core 5.11.0 创建测试替身 协程测试库 kotlinx-coroutines-test runTest / TestDispatcher 测试执行器(JUnit5 Platform) 加载 kotlinx-coroutines-test 扩展 → 处理协程调度 协程 Worker(SUT) 使用 StandardTestDispatcher 隔离调度 关键依赖: 1. junit-jupiter 决定测试生命周期;2. mockito-kotlin 提供协程安全的 mock;3. kotlinx-coroutines-test 控制虚拟时间 三者缺一不可,且版本必须互相兼容。 --- #### 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并逐步为其编写健壮的单元测试。