服务层为@Transactional时如何回滚单元测试
Posted
技术标签:
【中文标题】服务层为@Transactional时如何回滚单元测试【英文标题】:How to rollback unit test while service layer is @Transactional 【发布时间】:2017-12-11 06:34:00 【问题描述】:我正在使用 Spring Boot 1.5.2.RELEASE 并且我的服务类带有注释
@Service
@Transactional(rollbackFor = Exception.class)
我的单元测试类注释为:
@RunWith(SpringRunner.class)
@SpringBootTest
我希望在测试完成后回滚通过单元测试方法对数据库所做的更改。
建议的解决方案之一是在测试类上添加@Transactional
注解,我试过了,但这个解决方案会产生一些问题,就是有时测试事务会回滚(即使没有在服务事务完成之前抛出异常!)。
回滚测试还有其他好的解决方案吗?
【问题讨论】:
【参考方案1】:在测试类上使用@Transactional
的解决方案是执行此操作的标准方法。 Spring Tx 不可能突然回滚事务,因此我建议您仔细研究您遇到的问题,而不是发明其他解决方案。
【讨论】:
也许这是迄今为止最好的建议,我将深入研究我的测试方法,看看是什么导致了这种行为。【参考方案2】:如果没有更改默认行为,所有更改都将被回滚。而且您没有事务传播级别 = REQUIRES_NEW 的类/方法,因为它启动独立事务并且可以使用外部事务独立提交或回滚
事务回滚和提交行为
默认情况下,测试事务会自动回滚 完成测试;然而,事务提交和回滚 可以通过@Commit 和@Rollback 以声明方式配置行为 注释。
@Rollback
@Rollback 指示事务是否为事务性测试 方法应该在测试方法完成后回滚。如果 true,事务回滚;否则,交易是 已提交(另请参阅@Commit)。集成测试的回滚语义 在 Spring TestContext Framework 中默认为 true 即使 @Rollback 没有明确声明。
当声明为类级别注解时,@Rollback 定义 测试类中所有测试方法的默认回滚语义 等级制度。当声明为方法级注解时,@Rollback 定义特定测试方法的回滚语义,可能 覆盖类级别的 @Rollback 或 @Commit 语义。
【讨论】:
奇怪,我没有使用新的传播,默认行为是不回滚,你有什么建议? 1) 我写道 - '而你没有'。 2) 即使调用是测试完成后回滚中的成功事务。这是测试的默认行为。如果您需要保存更改并且不进行回滚,请在测试类或方法中使用 @Rollback(false)【参考方案3】:来自docs:
默认情况下,测试事务会自动回滚 完成测试;但是,事务提交和回滚行为可以通过 @Commit 和 @Rollback 注释以声明方式进行配置。
您的评论:
有时测试事务会回滚(即使没有 在服务事务完成之前抛出异常!)!
对我来说没有意义。如果回滚,您如何知道 txn 是否完成?正如我引用上面的文档一样,异常对测试无关紧要。
【讨论】:
在控制台中我看到了日志:回滚事务,并且有时(并非总是)在我的单元测试方法中调用某些方法之前记录。 @MahmoudS 测试完成后测试数据是否留在数据库中? 当我在测试类中使用 transacional 时,测试数据不会留下,但正如我所说,有时测试会无缘无故回滚并跳过调用某些方法! “跳过调用某些方法”与回滚无关。你的问题陈述是错误的。 不不,我很清楚我需要另一个解决方案,而不是在测试类上使用事务注释,因为它有时会跳过调用某些方法!!!!以上是关于服务层为@Transactional时如何回滚单元测试的主要内容,如果未能解决你的问题,请参考以下文章
springboot单元测试自动回滚:@Transactional