Issue
I've been trying to test out @TransactionalEvents
(a feature of Spring 4.2 rel="noreferrer">https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2) with our existing Spring JUnit Tests (run via either @TransactionalTestExecutionListener
or subclassing AbstractTransactionalUnit4SpringContextTests
but, it seems like there's a forced choice -- either run the test without a @Rollback
annotation, or the events don't fire. Has anyone come across a good way to test @TransactionalEvents while being able to @Rollback tests?
Solution
Stéphane Nicoll is correct: if the TransactionPhase
for your @TransactionalEventListener
is set to AFTER_COMMIT
, then having a transactional test with automatic rollback semantics doesn't make any sense because the event will never get fired.
In other words, there is no way to have an event fired after a transaction is committed if that transaction is never committed.
So if you really want the event to be fired, you have to let the transaction be committed (e.g., by annotating your test method with @Commit
). To clean up after the commit, you should be able to use @Sql
in isolated mode to execute cleanup scripts after the transaction has committed. For example, something like the following (untested code) might work for you:
@Transactional
@Commit
@Sql(scripts = "/cleanup.sql", executionPhase = AFTER_TEST_METHOD,
config = @SqlConfig(transactionMode = TransactionMode.ISOLATED))
@Test
public void test() { /* ... */ }
Regards,
Sam (author of the Spring TestContext Framework)
Answered By - Sam Brannen
Answer Checked By - Timothy Miller (JavaFixing Admin)