From 484dd96606fb0ebbf72d335a3adc4be5213616ee Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 3 Feb 2016 14:51:13 +0100 Subject: [PATCH] Throw exception if TxMgr cannot be retrieved for @Transactional test Prior to this commit, a @Transactional integration test would silently be executed without a transaction if the transaction manager could not be retrieved from the application context -- for example, it no such bean was defined or if multiple beans were present but none satisfied the qualifier. This commit addresses this issue by throwing an IllegalStateException if the PlatformTransactionManager cannot be retrieved for a @Transactional test. Issue: SPR-13895 (cherry picked from commit 6d2b9a013602ee2c06d6e30532635f09ae5795d6) --- .../TransactionalTestExecutionListener.java | 6 ++++ ...ansactionalTestExecutionListenerTests.java | 32 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java index 978dced76e4..6ae8d4bd9a5 100644 --- a/spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java +++ b/spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java @@ -186,6 +186,12 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis } tm = getTransactionManager(testContext, transactionAttribute.getQualifier()); + + if (tm == null) { + throw new IllegalStateException(String.format( + "Failed to retrieve PlatformTransactionManager for @Transactional test for test context %s.", + testContext)); + } } if (tm != null) { diff --git a/spring-test/src/test/java/org/springframework/test/context/transaction/TransactionalTestExecutionListenerTests.java b/spring-test/src/test/java/org/springframework/test/context/transaction/TransactionalTestExecutionListenerTests.java index b01fc608e8a..8d4e015f27d 100644 --- a/spring-test/src/test/java/org/springframework/test/context/transaction/TransactionalTestExecutionListenerTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/transaction/TransactionalTestExecutionListenerTests.java @@ -155,6 +155,38 @@ public class TransactionalTestExecutionListenerTests { TransactionContextHolder.removeCurrentTransactionContext(); } + /** + * SPR-13895 + */ + @Test + public void transactionalTestWithoutTransactionManager() throws Exception { + TransactionalTestExecutionListener listener = new TransactionalTestExecutionListener() { + + protected PlatformTransactionManager getTransactionManager(TestContext testContext, String qualifier) { + return null; + } + }; + + Class clazz = TransactionalDeclaredOnClassLocallyTestCase.class; + + BDDMockito.> given(testContext.getTestClass()).willReturn(clazz); + Invocable instance = clazz.newInstance(); + given(testContext.getTestInstance()).willReturn(instance); + given(testContext.getTestMethod()).willReturn(clazz.getDeclaredMethod("transactionalTest")); + + assertFalse(instance.invoked); + TransactionContextHolder.removeCurrentTransactionContext(); + + try { + listener.beforeTestMethod(testContext); + fail("Should have thrown an IllegalStateException"); + } + catch (IllegalStateException e) { + assertTrue(e.getMessage().startsWith( + "Failed to retrieve PlatformTransactionManager for @Transactional test for test context")); + } + } + @Test public void beforeTestMethodWithTransactionalDeclaredOnClassLocally() throws Exception { assertBeforeTestMethodWithTransactionalTestMethod(TransactionalDeclaredOnClassLocallyTestCase.class);