Rest Assured测试Spring Boot时首个测试执行后成员变量变为null
JUnit5测试类成员变量跨测试方法为空的原因及解决方案
核心原因
- JUnit 5 默认的测试实例生命周期为
PER_METHOD:每执行一个测试方法前,都会重新创建一个测试类RestServiceTestApplicationTests的全新实例,不同测试方法的类成员变量完全隔离,不会共享状态。 - 你在
getWholeFolders方法中给folderList赋值,实际是赋值给第一个测试实例的成员变量,该方法执行完毕后实例就被销毁。执行getRandomFolderNumber时使用的是新实例,未经过赋值的folderList自然为null。
可选解决方案
- 方案1:调整测试实例生命周期(推荐,适合有依赖的测试场景)
在测试类上添加@TestInstance(TestInstance.Lifecycle.PER_CLASS)注解,让整个测试类仅生成一个实例,即可实现成员变量跨测试方法共享。额外需要添加@TestMethodOrder(OrderAnnotation.class)控制测试执行顺序,给getWholeFolders加@Order(1)、getRandomFolderNumber加@Order(2),保证初始化方法先执行。
示例代码:@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestMethodOrder(OrderAnnotation.class) class RestServiceTestApplicationTests { // 原有成员变量不变 @Test @Order(1) public void getWholeFolders() { // 原有逻辑不变 } @Test @Order(2) public void getRandomFolderNumber() { // 原有逻辑不变 } } - 方案2:前置初始化
将获取folderList的逻辑放到@BeforeEach注解修饰的方法中,每个测试方法执行前都会自动执行初始化逻辑,缺点是会重复调用/api/opening接口。 - 方案3:合并测试逻辑
本身第二个测试强依赖第一个测试的执行结果,不符合单元测试独立无依赖的设计原则,你可以直接把两个逻辑合并到同一个测试方法中,无需拆分。 - 方案4:设置为静态变量(不推荐)
把folderList修饰为static静态变量,静态变量属于类而非实例,可跨实例共享。但静态变量会在整个测试上下文生效,容易被其他测试类修改导致不可预期的问题。
内容的提问来源于stack exchange,提问作者Wicaledon
相关产品推荐
相关产品推荐

