使用@MybatisTest时Testcontainers容器数据库无法插入记录
问题:@MybatisTest下MyBatis插入数据不生效(Testcontainers+Database Rider)
使用SpringBoot+MyBatis+MySQL构建RESTful API,采用Testcontainers和Database Rider测试MyBatis Mapper时,遇到以下问题:
- INSERT操作测试中,MyBatis返回插入成功(断言
actual == 1通过),但Docker容器数据库中无新增记录 - Database Rider的
@ExpectedDataSet断言失败:articles表预期行数1,实际为0 - 切换为
@SpringBootTest时插入正常,但测试启动速度慢
已排查情况:
- SELECT测试正常,DataSource配置无问题
- MySQL日志显示INSERT语句已接收,但未写入数据库
- UPDATE测试同样存在语句执行但不生效的问题
原因分析
@MybatisTest默认会为每个测试方法开启事务,并在测试结束后自动回滚事务。而Database Rider的@ExpectedDataSet是在测试方法的事务外部查询数据库,因此无法看到未提交的插入/更新数据,导致断言失败。
解决方案
方案1:给测试方法添加@Commit注解
强制测试方法执行完成后提交事务,让Database Rider能查询到提交的数据:
@Nested class InsertTest { @Test @DataSet("dataset/empty.yml") @ExpectedDataSet("dataset/inserted.yml") @Commit // 新增注解,提交事务 void insert_returnedNumberInserted() { // given String id = "************************************"; String title = "Title"; String body = "Body"; LocalDateTime createdAt = LocalDateTime.of(1970, 1, 1, 0, 0, 0); LocalDateTime updatedAt = LocalDateTime.of(1970, 1, 1, 0, 0, 0); ArticleEntity articleEntity = new ArticleEntity(id, title, body, createdAt, updatedAt); // when int actual = target.insert(articleEntity); // then assertEquals(1, actual); } }
方案2:禁用测试类的事务管理
在测试类上添加注解,让整个测试类不使用事务:
@DBRider @MybatisTest @Testcontainers @ActiveProfiles(profiles = "test") @Transactional(propagation = Propagation.NOT_SUPPORTED) // 禁用事务 public class ArticleEntityMapperTest { @Autowired private ArticleEntityMapper target; // ... 测试代码 }
方案3:配置Database Rider参与当前事务
修改dbunit.yml,让DBRider使用测试方法的事务上下文:
properties: caseSensitiveTableNames: true useTransaction: true # 新增配置,使用当前事务
此方案需确保DBRider与Spring事务上下文兼容,前两种方案更直接高效。
内容的提问来源于stack exchange,提问作者hiroaki
相关产品推荐
相关产品推荐

