Skip to content

Commit 6d2b9a0

Browse files
committed
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
1 parent d6648a0 commit 6d2b9a0

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ public void beforeTestMethod(final TestContext testContext) throws Exception {
186186
}
187187

188188
tm = getTransactionManager(testContext, transactionAttribute.getQualifier());
189+
190+
if (tm == null) {
191+
throw new IllegalStateException(String.format(
192+
"Failed to retrieve PlatformTransactionManager for @Transactional test for test context %s.",
193+
testContext));
194+
}
189195
}
190196

191197
if (tm != null) {

spring-test/src/test/java/org/springframework/test/context/transaction/TransactionalTestExecutionListenerTests.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,38 @@ public void cleanUpThreadLocalStateForSubsequentTestClassesInSuite() {
155155
TransactionContextHolder.removeCurrentTransactionContext();
156156
}
157157

158+
/**
159+
* SPR-13895
160+
*/
161+
@Test
162+
public void transactionalTestWithoutTransactionManager() throws Exception {
163+
TransactionalTestExecutionListener listener = new TransactionalTestExecutionListener() {
164+
165+
protected PlatformTransactionManager getTransactionManager(TestContext testContext, String qualifier) {
166+
return null;
167+
}
168+
};
169+
170+
Class<? extends Invocable> clazz = TransactionalDeclaredOnClassLocallyTestCase.class;
171+
172+
BDDMockito.<Class<?>> given(testContext.getTestClass()).willReturn(clazz);
173+
Invocable instance = clazz.newInstance();
174+
given(testContext.getTestInstance()).willReturn(instance);
175+
given(testContext.getTestMethod()).willReturn(clazz.getDeclaredMethod("transactionalTest"));
176+
177+
assertFalse(instance.invoked);
178+
TransactionContextHolder.removeCurrentTransactionContext();
179+
180+
try {
181+
listener.beforeTestMethod(testContext);
182+
fail("Should have thrown an IllegalStateException");
183+
}
184+
catch (IllegalStateException e) {
185+
assertTrue(e.getMessage().startsWith(
186+
"Failed to retrieve PlatformTransactionManager for @Transactional test for test context"));
187+
}
188+
}
189+
158190
@Test
159191
public void beforeTestMethodWithTransactionalDeclaredOnClassLocally() throws Exception {
160192
assertBeforeTestMethodWithTransactionalTestMethod(TransactionalDeclaredOnClassLocallyTestCase.class);

0 commit comments

Comments
 (0)