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的好方法,同时能够@回滚测试?
StéphaneNicoll是正确的:如果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 传播添加到业务代码中并不总是可以接受的。这会修改业务流程行为。
所以我们应该假设我们只能改变测试部分。
@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 传播修饰的测试组件中。该解决方案不会修改测试之外的其他逻辑。
@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 脚本,否则我们会引入提交的修改数据的副作用。
| 归档时间: |
|
| 查看次数: |
1603 次 |
| 最近记录: |