junit 4 的 @before 和 @beforeclass 分别对应 junit 5 的 @beforeeach 和 @beforeall:@beforeeach 在每个测试方法前执行,@beforeall 在所有测试方法前执行一次且必须为静态方法。

Java 中注解本身不直接执行环境初始化,但可以通过结合 JUnit(如 JUnit 4 或 JUnit 5)的生命周期注解和自定义扩展机制,在单元测试中实现自动化、声明式的环境初始化。
@Before / @BeforeEach:最常用的方法
这是最直接、无需额外配置的方式。JUnit 4 使用 @Before,JUnit 5 使用 @BeforeEach,它们修饰的方法会在每个测试方法执行前运行,适合做数据库连接、Mock 初始化、临时文件创建等操作。
- JUnit 5 示例:
void setUp() {
database = new InMemoryDatabase();
database.start();
mockService = Mockito.mock(ExternalService.class);
}
该方式简单可靠,适合项目级统一初始化逻辑,缺点是无法按测试类或测试方法差异化控制(除非配合条件判断)。
@BeforeAll / @AfterAll:共享昂贵资源
当初始化成本高(如启动嵌入式 Redis、加载大型配置),可用 @BeforeAll(JUnit 5)或 @BeforeClass(JUnit 4)在所有测试方法前执行一次。注意:该方法必须是 static 的,且不能访问实例变量。
- 典型用法:
static void initSharedResources() {
embeddedRedis = RedisServer.builder().port(6379).build();
embeddedRedis.start();
}
搭配 @AfterAll 清理资源,确保测试间隔离性。适用于跨测试共享的轻量服务,但需注意并发测试时的线程安全问题(JUnit 5 默认串行执行测试类,可配置并行)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
@ExtendWith + 自定义 Extension(JUnit 5 推荐)
这是最灵活、可复用的方式。通过实现 Extension 接口(如 TestInstancePostProcessor、BeforeEachCallback),再用 @ExtendWith(YourExtension.class) 声明式启用,实现“注解驱动”的初始化逻辑。
- 例如,定义一个
@WithDatabase注解:
@Retention(RetentionPolicy.RUNTIME)
public @interface WithDatabase {}
再编写对应 Extension,在 beforeEach() 中检查该注解,自动启动/清空内存库。这样不同测试类只需加一行 @WithDatabase,无需重复写 setUp 代码。
优势在于解耦、可组合(比如同时用 @WithDatabase 和 @WithMockUser),也便于在模块间复用。
@ContextConfiguration(Spring Boot Test 场景)
若使用 Spring Boot Test,@ContextConfiguration 或更常用的 @SpringBootTest 会自动触发 Spring 上下文加载,并配合 @TestConfiguration、@MockBean 等完成环境装配。
- 例如:
@Import(TestConfig.class)
class UserServiceTest { ... }
此时 Spring 容器就是“初始化环境”,数据源、事务管理器、Mock Bean 都由框架自动注入。适合集成度较高的测试,但启动较慢,不属于纯单元测试范畴。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










