【问题标题】:How to rollback unit test while service layer is @Transactional服务层为@Transactional时如何回滚单元测试
【发布时间】:2017-12-11 06:34:00
【问题描述】:

我正在使用 Spring Boot 1.5.2.RELEASE 并且我的服务类带有注释

@Service
@Transactional(rollbackFor = Exception.class)

我的单元测试类注释为:

@RunWith(SpringRunner.class)
@SpringBootTest

我希望在测试完成后回滚通过单元测试方法对数据库所做的更改。

建议的解决方案之一是在测试类上添加@Transactional注解,我试过了,但这个解决方案会产生一些问题,就是有时测试事务会回滚(即使没有在服务事务完成之前抛出异常!)。

回滚测试还有其他好的解决方案吗?

【问题讨论】:

    标签: spring spring-boot junit spring-transactions spring-test


    【解决方案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 时,测试数据不会留下,但正如我所说,有时测试会无缘无故回滚并跳过调用某些方法!
    • “跳过调用某些方法”与回滚无关。你的问题陈述是错误的。
    • 不不,我很清楚我需要另一个解决方案,而不是在测试类上使用事务注释,因为它有时会跳过调用某些方法!!!!
    猜你喜欢
    • 1970-01-01
    • 2013-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-13
    • 1970-01-01
    • 2020-02-10
    相关资源
    最近更新 更多