Java 测试与 JUnit
JUnit 5 如何组织测试、断言与生命周期:把行为锁在可重复反馈里。
#type / concept
#status / growing
#tech / dev
#resource / java
[!info] 关联笔记
Java 测试与 JUnit
这个概念为什么出现
没有自动化测试,重构与并发修改只能靠勇气。JUnit 是 Java 生态最常见的测试框架;与构建工具集成后成为 CI 门禁。
[!abstract] 一句话理解 用 JUnit 5 写可独立运行的测试方法,断言期望行为;通过构建工具在 CI 重复执行,锁住回归。
最小可运行示例
场景:定价函数的表意测试
// src/test/java 概念
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class PricingTest {
@Test
void price_multiplies_units_by_100() {
assertEquals(200, new Pricing().price(2));
}
@Test
void price_rejects_negative() {
assertThrows(IllegalArgumentException.class, () -> new Pricing().price(-1));
}
}
class Pricing {
int price(int units) {
if (units < 0) throw new IllegalArgumentException("units");
return units * 100;
}
}
构建:
mvn -q test
# 或
./gradlew test
结合场景再看三个关注点
- 测试名描述行为。
- 异常也是契约。
- 快测优先,IO/DB 放集成测试。
核心概念与准确模型
1. JUnit 5 结构
- Jupiter 引擎
@Test/@BeforeEach/@ParameterizedTest
2. 断言
assertEquals/assertThrows/assertAll
3. 与构建
- Surefire 跑单元
- Failsafe 跑集成(约定)
边界情况与反直觉行为
- 测试顺序不保证。
- 共享可变静态状态导致片状失败。
- 过度 mock 测不到真实集成。
常见误区
[!warning] 常见误区:只追求覆盖率数字 覆盖率是指标不是目标;断言质量更重要。
工程实践
- Arrange-Act-Assert。
- 一个行为一个测试焦点。
- 测试数据建造器。
- CI 失败即阻断合并。
本节总结
- JUnit 锁行为
- 与构建/CI 一体
- 快测与集成分层
自测题
- 为什么测试不应依赖执行顺序?
- assertThrows 验证什么?
参考答案
- 并行与过滤执行会打乱顺序,顺序耦合即脆弱。
- 某调用抛出期望类型(及可选消息)异常。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| JUnit 5 User Guide | 官方 | 用法 |