第 20 章:单元测试与调试
20.1 JUnit 5 与 Mockito
1. JUnit 5 简介
JUnit 5 是 Java 生态中最流行的单元测试框架之一,Kotlin 可以无缝集成 JUnit 5 进行单元测试。
核心组件:
- JUnit Jupiter:提供测试注解和断言 API。
- JUnit Platform:测试引擎的运行基础。
- JUnit Vintage:兼容旧版 JUnit 4 测试。
依赖配置(Gradle):
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")
}
2. 编写 Kotlin 单元测试
基本测试示例:
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
class CalculatorTest {
@Test
fun `test addition`() {
val calculator = Calculator()
assertEquals(4, calculator.add(2, 2))
}
}
常用注解:
@Test:标记测试方法。@BeforeEach/@AfterEach:每个测试前后的操作。@DisplayName:自定义测试显示名称。
3. Mockito 模拟依赖
Mockito 用于模拟外部依赖(如数据库、网络请求),隔离测试目标代码。
依赖配置(Gradle):
testImplementation("org.mockito:mockito-core:4.5.1")
testImplementation("org.mockito.kotlin:mockito-kotlin:4.0.0") // Kotlin 扩展
使用示例:
import org.junit.jupiter.api.Test
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
class UserServiceTest {
private val userRepository = mock<UserRepository>()
private val userService = UserService(userRepository)
@Test
fun `getUserById should return user`() {
val expectedUser = User(id = 1, name = "Alice")
whenever(userRepository.findById(1)).thenReturn(expectedUser)
val result = userService.getUserById(1)
assertEquals(expectedUser, result)
verify(userRepository).findById(1) // 验证调用
}
}
4. Kotlin 与 Mockito 的注意事项
- 避免
when关键字冲突:使用 Mockito-Kotlin 的whenever。 - 模拟 final 类:Kotlin 默认类为 final,需在
build.gradle中启用 Mockito 扩展:testImplementation("org.mockito:mockito-inline:4.5.1")
5. 进阶技巧
- 参数化测试:使用
@ParameterizedTest和@ValueSource。 - 断言增强:结合 Kotlin 的
assertAll进行多条件验证。 - Mockito 验证:
verify方法检查模拟对象的交互行为。
最佳实践:
- 优先测试业务逻辑而非实现细节。
- 使用
given-when-then结构组织测试代码。- 为测试类和方法命名时采用描述性语言(如反引号语法)。
