Java单元测试核心是写得准、跑得稳、看得懂、改得快;应聚焦类本身行为,用JUnit 5+Mockito构建轻量骨架,遵循Given-When-Then结构,只验证核心逻辑,规避伪测试。

编写规范的 Java 测试代码,核心不是“写得全”,而是“写得准、跑得稳、看得懂、改得快”。它不依赖框架堆砌,而取决于对可测试性设计的理解和对测试职责边界的把握。
用 JUnit 5 + Mockito 搭建干净测试骨架
避免 Spring Test 全量启动——基础通关阶段应聚焦类本身行为。只引入最小必要依赖:
- junit-jupiter-api 和 junit-jupiter-engine:声明和运行测试
- mockito-core(或 mockito-inline):隔离外部协作对象,如 service、repo、工具类
- 不用
@SpringBootTest,不加@ContextConfiguration,不启动 IOC 容器
测试类命名统一为 XXXTest,与被测类同包(非必须但利于访问包级方法),使用标准构造注入或字段注入被测对象,不依赖反射或复杂初始化逻辑。
让被测代码天然支持测试
测试难,往往是因为代码本身没为测试留出口。关键改造点包括:
-
把静态依赖转成参数或成员:比如
EnvUtils.region改为构造函数入参,或抽取为接口(RegionProvider)并注入 - 拆分 IO 与逻辑:数据库读写、HTTP 调用、时间获取等,全部提取到独立方法或接口中,主逻辑只处理纯数据
-
降低方法粒度,暴露包级可见性:私有方法若含核心算法,可改为
package-private(无修饰符),方便直接验证,无需反射或过度 mock
写测试要遵循 Given-When-Then 结构
每条测试用例应清晰表达“什么前提下,执行什么操作,得到什么结果”。例如:
Given 用户输入手机号为空
When 调用 validatePhone()
Then 抛出 IllegalArgumentException,且消息含 "phone"
断言优先用语义化方法:assertThrows()、assertTrue()、assertEquals();避免 System.out.println() 或空断言。每个测试只验证一个关注点,失败时能立刻定位问题域。
不测什么,和测什么一样重要
基础实战中需主动规避以下“伪测试”:
- 不测日志打印、线程休眠、静态工具类调用(除非你正测试该工具类)
- 不测数据库 CRUD 本身(交给集成测试或 H2 验证 schema,非单元测试范畴)
- 不为 getter/setter、toString、构造函数等样板代码单独写测试(除非有特殊逻辑)
- 不 mock 自己的被测类,也不在测试里 new 多个同类实例制造状态干扰
测试代码也是生产代码——它要可读、可维护、不随业务逻辑频繁失效。写的时候多问一句:“如果这段业务逻辑改了,这个测试是应该失败,还是应该不动?”答案应是前者。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











