@beforeeach 和 @aftereach 是 junit 5 保障测试隔离性的核心机制,确保每个@test在干净独立环境中运行;它们必须是非静态、无参方法,分别用于每次测试前初始化和测试后清理,避免状态污染。

@BeforeEach 和 @AfterEach 是 JUnit 5 中保障测试隔离性的核心机制,它们确保每个 @Test 方法都在干净、独立的环境中运行,避免状态污染。
为什么必须用 @BeforeEach 而不是在@Test里手动初始化
JUnit 为每个测试方法创建全新的测试类实例。如果把对象初始化写在@Test方法内部,虽然也能工作,但容易遗漏清理逻辑、重复代码多、难以统一管理资源。而 @BeforeEach/@AfterEach 由框架自动调用,强制执行,更可靠。
- @BeforeEach 方法在每个@Test前执行一次,适合创建新对象、打开临时文件、启动内存数据库连接等
- @AfterEach 方法在每个@Test后执行一次,适合关闭流、清空集合、回滚事务、释放锁等
- 这两个方法必须是非静态的(与 @BeforeAll/@AfterAll 不同),且不能带参数
@BeforeEach 中该放什么,怎么放才安全
所有需要“每次测试都全新”的对象,都应声明为测试类的普通字段(非 static),并在 @BeforeEach 中赋值:
- 例如:Calculator calc; → @BeforeEach 中 new Calculator()
- 不要在字段声明时直接初始化(如 Calculator calc = new Calculator()),否则 @BeforeEach 无法覆盖,可能残留上一个测试的状态
- 如果涉及外部资源(如 H2 内存库),应在 @BeforeEach 中重建 DataSource 实例,而非复用静态单例——否则系统属性或连接池状态会跨测试污染
@AfterEach 的典型清理操作
清理目标是“让环境回到测试开始前的样子”,重点不是“彻底销毁”,而是“解除对后续测试的影响”:
- 关闭 FileInputStream / FileOutputStream / Socket 等需显式释放的资源
- 清空静态缓存(如 Map
cache)——若必须用静态变量,需在 @AfterEach 中 clear() - 重置模拟对象行为(如 Mockito.reset(mockService))
- 调用数据库事务回滚(如果使用嵌入式 DB 且未自动提交)
常见陷阱与规避方式
看似简单,但几个细节出错就会导致测试间相互干扰:
- 误把 @BeforeEach 方法写成 static → JUnit 5 会直接忽略,不报错也不执行
- 在 @BeforeEach 中修改了 static 字段但没在 @AfterEach 中还原 → 后续测试读到脏数据
- 依赖全局 System.setProperty() 但没在 @AfterEach 中 restore → 影响其他测试甚至整个测试套件
- 忘记关闭 AutoCloseable 资源(如 try-with-resources 未覆盖所有路径)→ 可能触发文件句柄耗尽或连接泄漏
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











