TestNg+Spring+H2环境下如何避免测试回滚及实现测试间数据共享?
解决Spring Boot + TestNG集成测试中跨测试方法无法读取数据的问题
我来帮你分析下当前遇到的问题,然后一步步给出解决方案:
1. 先修正测试方法的访问修饰符
你现在的m1()和m2()都是private方法,这会引发两个关键问题:
- TestNG无法正确识别并处理这类私有测试方法,就算看起来能运行,Spring的事务注解也无法生效
- Spring的AOP代理机制无法作用于
private方法,导致@Rollback(false)完全没起作用——m1()里保存数据的事务最终还是会被回滚,m2()自然读不到任何数据
修正方式:把两个测试方法改成public:
@Test(priority = 1) @Rollback(false) public void m1() { // save data. } @Test(priority = 2) // 调整优先级,确保m1执行完成后再跑m2 @Rollback(false) public void m2() { // retrieve saved data. }
2. 调整测试方法的执行顺序
你给两个方法都设置了priority = 1,TestNG会默认并行执行这两个方法,这就会出现m2在m1还没完成数据保存时就去读取,自然会失败。
修正方式:给m2设置更高的优先级(比如priority = 2),强制让m1先执行完毕,再启动m2的逻辑。
3. 确保H2数据库配置正确
在你的application-test.properties(或yml)文件里,要保证H2内存数据库的配置能支持跨事务读取,示例配置如下:
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.show-sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect # 确保事务提交后其他连接能读取到数据 spring.jpa.properties.hibernate.connection.autocommit=false
其中DB_CLOSE_DELAY=-1是为了让H2内存数据库在测试全程保持连接不关闭,避免数据意外丢失。
4. 可选:用@TestInstance共享测试上下文
如果需要在多个测试方法间共享同一个Spring上下文(包括数据库连接状态),可以在测试类上添加@TestInstance(TestInstance.Lifecycle.PER_CLASS)注解,这样TestNG会为整个测试类创建一个实例,而非每个测试方法都新建一个,保证上下文的一致性:
@ActiveProfiles("test") @SpringBootTest(classes = APP.class, webEnvironment = WebEnvironment.RANDOM_PORT) @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class IntegrationTest extends AbstractTestNGSpringContextTests { // ... 测试方法 }
验证步骤
- 把测试方法改为
public,调整好优先级顺序 - 检查H2的配置是否符合上述要求
- 重新运行测试,此时
m1保存的数据应该能被m2正常读取到了
内容的提问来源于stack exchange,提问作者adiraju uttej
相关产品推荐
相关产品推荐

