测试@TransactionalEvents和@Rollback

ada*_*dam 3 junit spring spring-test spring-transactions

我一直在尝试使用我们现有的Spring 进行测试@TransactionalEvents(Spring 4.2的功能https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2) JUnit测试(通过@TransactionalTestExecutionListener或子类运行AbstractTransactionalUnit4SpringContextTests,但是似乎有一个强制选择-运行没有@Rollback注释的测试,或者事件不触发。有没有人遇到测试@TransactionalEvents的好方法,同时能够@回滚测试?

Sam*_*nen 5

StéphaneNic​​oll是正确的:如果TransactionPhase您的for @TransactionalEventListener设置为AFTER_COMMIT,则使用自动回滚语义进行事务测试没有任何意义,因为该事件永远不会触发。

换句话说,如果从未提交事务,则在提交事务后无法触发事件。

因此,如果您确实希望触发该事件,则必须让该事务被提交(例如,通过使用注释您的测试方法@Commit)。要在提交后进行清理,您应该能够在事务提交@Sql隔离模式使用执行清理脚本。例如,类似以下内容(未经测试的代码)的内容可能对您有用:

@Transactional
@Commit
@Sql(scripts = "/cleanup.sql", executionPhase = AFTER_TEST_METHOD,
     config = @SqlConfig(transactionMode = TransactionMode.ISOLATED))
@Test
public void test() { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

问候,

Sam(Spring TestContext Framework的作者


小智 5

Marco 的解决方案有效,但将 REQUIRES_NEW 传播添加到业务代码中并不总是可以接受的。这会修改业务流程行为。

所以我们应该假设我们只能改变测试部分。

溶液1

@TestComponent // can be used with spring boot
public class TestApplicationService {

    @Autowired
    public MyApplicationService service;

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void doSomething() {
        service.doSomething();
   }
}
Run Code Online (Sandbox Code Playgroud)

这将真实的服务包装到可以用 REQUIRES_NEW 传播修饰的测试组件中。该解决方案不会修改测试之外的其他逻辑。

解决方案2

@Transactional
@Sql(scripts = "/cleanup.sql", executionPhase = AFTER_TEST_METHOD,
     config = @SqlConfig(transactionMode = TransactionMode.ISOLATED))
@Test
public void test() { 
    MyApplicationService target = // ...
    target.doSomething();
    TestTransaction.flagForCommit(); //Spring-test since 4.1 - thx for Sam Brannen
    TestTransaction.end();
    // the event is now received by MyListener
    // assertions on the side effects of MyListener
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这是最简单的解决方案。我们可以结束测试事务并将其标记为提交。这强制处理事务事件。如果测试更改数据,则必须指定清理 SQL 脚本,否则我们会引入提交的修改数据的副作用。