From 973582e7dfecbc9b5f78d38b57fac4d04994379b Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 17 May 2015 17:14:09 +0200 Subject: [PATCH] Introduce TestContextManager cache in SpringClassRule In order to simplify configuration of the SpringMethodRule and to ensure that the correct TestContextManager is always retrieved for the currently executing test class, this commit introduces a static TestContextManager cache in SpringClassRule. In addition, since it is not foreseen that SpringClassRule and SpringMethodRule should be able to be subclassed, their internal methods are now private instead of protected. Issue: SPR-7731 --- .../context/junit4/rules/SpringClassRule.java | 133 +++++++++++------ .../junit4/rules/SpringMethodRule.java | 141 ++++++++---------- .../junit4/rules/BaseAppCtxRuleTests.java | 25 ++-- ...sicAnnotationConfigWacSpringRuleTests.java | 2 +- ...rTransactionAnnotationSpringRuleTests.java | 2 +- .../ClassLevelDisabledSpringRuleTests.java | 2 +- .../EnabledAndIgnoredSpringRuleTests.java | 2 +- ...gBeforeAndAfterMethodsSpringRuleTests.java | 6 +- .../rules/ParameterizedSpringRuleTests.java | 2 +- .../ProgrammaticTxMgmtSpringRuleTests.java | 2 +- .../junit4/rules/RepeatedSpringRuleTests.java | 2 +- .../rules/Subclass1AppCtxRuleTests.java | 28 +++- .../rules/Subclass2AppCtxRuleTests.java | 28 +++- .../junit4/rules/TimedSpringRuleTests.java | 2 +- .../TimedTransactionalSpringRuleTests.java | 2 +- ...ransactionalSqlScriptsSpringRuleTests.java | 2 +- 16 files changed, 224 insertions(+), 157 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/context/junit4/rules/SpringClassRule.java b/spring-test/src/main/java/org/springframework/test/context/junit4/rules/SpringClassRule.java index c57986cece0..be1ea7f8d3b 100644 --- a/spring-test/src/main/java/org/springframework/test/context/junit4/rules/SpringClassRule.java +++ b/spring-test/src/main/java/org/springframework/test/context/junit4/rules/SpringClassRule.java @@ -18,6 +18,8 @@ package org.springframework.test.context.junit4.rules; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -31,12 +33,13 @@ import org.springframework.test.context.TestContextManager; import org.springframework.test.context.junit4.statements.ProfileValueChecker; import org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks; import org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks; +import org.springframework.util.Assert; /** - * {@code SpringClassRule} is a custom JUnit {@link TestRule} that provides - * class-level functionality of the Spring TestContext Framework - * to standard JUnit tests by means of the {@link TestContextManager} and associated - * support classes and annotations. + * {@code SpringClassRule} is a custom JUnit {@link TestRule} that supports + * class-level features of the Spring TestContext Framework + * in standard JUnit tests by means of the {@link TestContextManager} and + * associated support classes and annotations. * *

In contrast to the {@link org.springframework.test.context.junit4.SpringJUnit4ClassRunner * SpringJUnit4ClassRunner}, Spring's rule-based JUnit support has the advantage @@ -46,7 +49,7 @@ import org.springframework.test.context.junit4.statements.RunBeforeTestClassCall * *

In order to achieve the same functionality as the {@code SpringJUnit4ClassRunner}, * however, a {@code SpringClassRule} must be combined with a {@link SpringMethodRule}, - * since {@code SpringClassRule} only provides the class-level features of the + * since {@code SpringClassRule} only supports the class-level features of the * {@code SpringJUnit4ClassRunner}. * *

Example Usage

@@ -56,7 +59,7 @@ import org.springframework.test.context.junit4.statements.RunBeforeTestClassCall * public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); * * @Rule - * public final SpringMethodRule springMethodRule = new SpringMethodRule(this); + * public final SpringMethodRule springMethodRule = new SpringMethodRule(); * * // ... * } @@ -88,39 +91,20 @@ public class SpringClassRule implements TestRule { private static final Log logger = LogFactory.getLog(SpringClassRule.class); /** - * This field is {@code volatile} since a {@code SpringMethodRule} can - * potentially access it from a different thread, depending on the type - * of JUnit runner in use. + * Cache of {@code TestContextManagers} keyed by test class. */ - private volatile TestContextManager testContextManager; + private static final Map, TestContextManager> testContextManagerCache = + new ConcurrentHashMap, TestContextManager>(64); /** - * Create a new {@link TestContextManager} for the supplied test class. - *

Can be overridden by subclasses. - * @param clazz the test class to be managed - */ - protected TestContextManager createTestContextManager(Class clazz) { - return new TestContextManager(clazz); - } - - /** - * Get the {@link TestContextManager} associated with this rule. - *

Will be {@code null} until the {@link #apply} method is invoked - * by a JUnit runner. - */ - protected final TestContextManager getTestContextManager() { - return this.testContextManager; - } - - /** - * Apply class-level functionality of the Spring TestContext + * Apply class-level features of the Spring TestContext * Framework to the supplied {@code base} statement. * - *

Specifically, this method creates the {@link TestContextManager} used - * by this rule and its associated {@link SpringMethodRule} and invokes the - * {@link TestContextManager#beforeTestClass() beforeTestClass()} and - * {@link TestContextManager#afterTestClass() afterTestClass()} methods + *

Specifically, this method retrieves the {@link TestContextManager} + * used by this rule and its associated {@link SpringMethodRule} and + * invokes the {@link TestContextManager#beforeTestClass() beforeTestClass()} + * and {@link TestContextManager#afterTestClass() afterTestClass()} methods * on the {@code TestContextManager}. * *

In addition, this method checks whether the test is enabled in @@ -132,14 +116,15 @@ public class SpringClassRule implements TestRule { * @param base the base {@code Statement} that this rule should be applied to * @param description a {@code Description} of the current test execution * @return a statement that wraps the supplied {@code base} with class-level - * functionality of the Spring TestContext Framework - * @see #createTestContextManager + * features of the Spring TestContext Framework + * @see #getTestContextManager * @see #withBeforeTestClassCallbacks * @see #withAfterTestClassCallbacks * @see #withProfileValueCheck + * @see #withTestContextManagerCacheEviction */ @Override - public Statement apply(final Statement base, final Description description) { + public Statement apply(Statement base, Description description) { Class testClass = description.getTestClass(); if (logger.isDebugEnabled()) { @@ -148,12 +133,13 @@ public class SpringClassRule implements TestRule { validateSpringMethodRuleConfiguration(testClass); - this.testContextManager = createTestContextManager(testClass); + TestContextManager testContextManager = getTestContextManager(testClass); Statement statement = base; - statement = withBeforeTestClassCallbacks(statement); - statement = withAfterTestClassCallbacks(statement); - statement = withProfileValueCheck(testClass, statement); + statement = withBeforeTestClassCallbacks(statement, testContextManager); + statement = withAfterTestClassCallbacks(statement, testContextManager); + statement = withProfileValueCheck(statement, testClass); + statement = withTestContextManagerCacheEviction(statement, testClass); return statement; } @@ -161,33 +147,46 @@ public class SpringClassRule implements TestRule { * Wrap the supplied {@code statement} with a {@code RunBeforeTestClassCallbacks} statement. * @see RunBeforeTestClassCallbacks */ - protected Statement withBeforeTestClassCallbacks(Statement statement) { - return new RunBeforeTestClassCallbacks(statement, getTestContextManager()); + private Statement withBeforeTestClassCallbacks(Statement statement, TestContextManager testContextManager) { + return new RunBeforeTestClassCallbacks(statement, testContextManager); } /** * Wrap the supplied {@code statement} with a {@code RunAfterTestClassCallbacks} statement. * @see RunAfterTestClassCallbacks */ - protected Statement withAfterTestClassCallbacks(Statement statement) { - return new RunAfterTestClassCallbacks(statement, getTestContextManager()); + private Statement withAfterTestClassCallbacks(Statement statement, TestContextManager testContextManager) { + return new RunAfterTestClassCallbacks(statement, testContextManager); } /** * Wrap the supplied {@code statement} with a {@code ProfileValueChecker} statement. * @see ProfileValueChecker */ - protected Statement withProfileValueCheck(Class testClass, Statement statement) { + private Statement withProfileValueCheck(Statement statement, Class testClass) { return new ProfileValueChecker(statement, testClass, null); } - private void validateSpringMethodRuleConfiguration(Class testClass) { + /** + * Wrap the supplied {@code statement} with a {@code TestContextManagerCacheEvictor} statement. + * @see TestContextManagerCacheEvictor + */ + private Statement withTestContextManagerCacheEviction(Statement statement, Class testClass) { + return new TestContextManagerCacheEvictor(statement, testClass); + } + + /** + * Throw an {@link IllegalStateException} if the supplied {@code testClass} + * does not declare a {@code public SpringMethodRule} field that is + * annotated with {@code @Rule}. + */ + private static final void validateSpringMethodRuleConfiguration(Class testClass) { Field ruleField = null; for (Field field : testClass.getFields()) { int modifiers = field.getModifiers(); if (!Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers) - && (SpringMethodRule.class.isAssignableFrom(field.getType()))) { + && SpringMethodRule.class.isAssignableFrom(field.getType())) { ruleField = field; break; } @@ -206,4 +205,44 @@ public class SpringClassRule implements TestRule { } } + /** + * Get the {@link TestContextManager} associated with the supplied test class. + * @param testClass the test class to be managed; never {@code null} + */ + static final TestContextManager getTestContextManager(Class testClass) { + Assert.notNull(testClass, "testClass must not be null"); + synchronized (testContextManagerCache) { + TestContextManager testContextManager = testContextManagerCache.get(testClass); + if (testContextManager == null) { + testContextManager = new TestContextManager(testClass); + testContextManagerCache.put(testClass, testContextManager); + } + return testContextManager; + } + } + + + private static class TestContextManagerCacheEvictor extends Statement { + + private final Statement next; + + private final Class testClass; + + + TestContextManagerCacheEvictor(Statement next, Class testClass) { + this.next = next; + this.testClass = testClass; + } + + @Override + public void evaluate() throws Throwable { + try { + next.evaluate(); + } + finally { + testContextManagerCache.remove(testClass); + } + } + } + } diff --git a/spring-test/src/main/java/org/springframework/test/context/junit4/rules/SpringMethodRule.java b/spring-test/src/main/java/org/springframework/test/context/junit4/rules/SpringMethodRule.java index 7f9dbc1a648..5c0255eabe2 100644 --- a/spring-test/src/main/java/org/springframework/test/context/junit4/rules/SpringMethodRule.java +++ b/spring-test/src/main/java/org/springframework/test/context/junit4/rules/SpringMethodRule.java @@ -38,13 +38,12 @@ import org.springframework.test.context.junit4.statements.RunBeforeTestMethodCal import org.springframework.test.context.junit4.statements.RunPrepareTestInstanceCallbacks; import org.springframework.test.context.junit4.statements.SpringFailOnTimeout; import org.springframework.test.context.junit4.statements.SpringRepeat; -import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; /** * {@code SpringMethodRule} is a custom JUnit {@link MethodRule} that - * provides instance-level and method-level functionality of the - * Spring TestContext Framework to standard JUnit tests by means + * supports instance-level and method-level features of the + * Spring TestContext Framework in standard JUnit tests by means * of the {@link TestContextManager} and associated support classes and * annotations. * @@ -56,8 +55,8 @@ import org.springframework.util.ReflectionUtils; * *

In order to achieve the same functionality as the {@code SpringJUnit4ClassRunner}, * however, a {@code SpringMethodRule} must be combined with a {@link SpringClassRule}, - * since {@code SpringMethodRule} only provides the method-level features of the - * {@code SpringJUnit4ClassRunner}. + * since {@code SpringMethodRule} only supports the instance-level and method-level + * features of the {@code SpringJUnit4ClassRunner}. * *

Example Usage

*
 public class ExampleSpringIntegrationTest {
@@ -66,7 +65,7 @@ import org.springframework.util.ReflectionUtils;
  *    public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
  *
  *    @Rule
- *    public final SpringMethodRule springMethodRule = new SpringMethodRule(this);
+ *    public final SpringMethodRule springMethodRule = new SpringMethodRule();
  *
  *    // ...
  * }
@@ -99,36 +98,10 @@ public class SpringMethodRule implements MethodRule { private static final Log logger = LogFactory.getLog(SpringMethodRule.class); - /** - * {@code SpringMethodRule} retains a reference to the {@code SpringClassRule} - * instead of the {@code TestContextManager}, since the class rule owns - * the {@code TestContextManager}. - */ - private final SpringClassRule springClassRule; - /** - * Construct a new {@code SpringMethodRule} for the supplied test instance. - * - *

The test class must declare a {@code public static final SpringClassRule} - * field (i.e., a constant) that is annotated with JUnit's - * {@link ClassRule @ClassRule} — for example: - * - *

 @ClassRule
-	 * public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
- * - * @param testInstance the test instance, never {@code null} - * @throws IllegalStateException if the test class does not declare an - * appropriate {@code SpringClassRule} constant. - */ - public SpringMethodRule(Object testInstance) { - Assert.notNull(testInstance, "testInstance must not be null"); - this.springClassRule = retrieveAndValidateSpringClassRule(testInstance.getClass()); - } - - /** - * Apply instance-level and method-level functionality - * of the Spring TestContext Framework to the supplied {@code base} + * Apply instance-level and method-level features of + * the Spring TestContext Framework to the supplied {@code base} * statement. * *

Specifically, this method invokes the @@ -148,7 +121,7 @@ public class SpringMethodRule implements MethodRule { * @param frameworkMethod the method which is about to be invoked on the test instance * @param testInstance the current test instance * @return a statement that wraps the supplied {@code base} with instance-level - * and method-level functionality of the Spring TestContext Framework + * and method-level features of the Spring TestContext Framework * @see #withBeforeTestMethodCallbacks * @see #withAfterTestMethodCallbacks * @see #withPotentialRepeat @@ -157,62 +130,53 @@ public class SpringMethodRule implements MethodRule { * @see #withProfileValueCheck */ @Override - public Statement apply(final Statement base, final FrameworkMethod frameworkMethod, final Object testInstance) { + public Statement apply(Statement base, FrameworkMethod frameworkMethod, Object testInstance) { + Class testClass = testInstance.getClass(); + if (logger.isDebugEnabled()) { logger.debug("Applying SpringMethodRule to test method [" + frameworkMethod.getMethod() + "]."); } + validateSpringClassRuleConfiguration(testClass); + + TestContextManager testContextManager = SpringClassRule.getTestContextManager(testClass); + Statement statement = base; - statement = withBeforeTestMethodCallbacks(frameworkMethod, testInstance, statement); - statement = withAfterTestMethodCallbacks(frameworkMethod, testInstance, statement); - statement = withTestInstancePreparation(testInstance, statement); - statement = withPotentialRepeat(frameworkMethod, testInstance, statement); - statement = withPotentialTimeout(frameworkMethod, testInstance, statement); - statement = withProfileValueCheck(frameworkMethod, testInstance, statement); + statement = withBeforeTestMethodCallbacks(statement, frameworkMethod, testInstance, testContextManager); + statement = withAfterTestMethodCallbacks(statement, frameworkMethod, testInstance, testContextManager); + statement = withTestInstancePreparation(statement, testInstance, testContextManager); + statement = withPotentialRepeat(statement, frameworkMethod, testInstance); + statement = withPotentialTimeout(statement, frameworkMethod, testInstance); + statement = withProfileValueCheck(statement, frameworkMethod, testInstance); return statement; } /** - * Get the {@link TestContextManager} associated with this rule. + * Wrap the supplied {@link Statement} with a {@code RunBeforeTestMethodCallbacks} statement. + * @see RunBeforeTestMethodCallbacks */ - protected final TestContextManager getTestContextManager() { - return this.springClassRule.getTestContextManager(); + private Statement withBeforeTestMethodCallbacks(Statement statement, FrameworkMethod frameworkMethod, + Object testInstance, TestContextManager testContextManager) { + return new RunBeforeTestMethodCallbacks(statement, testInstance, frameworkMethod.getMethod(), + testContextManager); } /** - * Wrap the supplied {@link Statement} with a {@code ProfileValueChecker} statement. - * @see ProfileValueChecker + * Wrap the supplied {@link Statement} with a {@code RunAfterTestMethodCallbacks} statement. + * @see RunAfterTestMethodCallbacks */ - protected Statement withProfileValueCheck(FrameworkMethod frameworkMethod, Object testInstance, Statement statement) { - return new ProfileValueChecker(statement, testInstance.getClass(), frameworkMethod.getMethod()); + private Statement withAfterTestMethodCallbacks(Statement statement, FrameworkMethod frameworkMethod, + Object testInstance, TestContextManager testContextManager) { + return new RunAfterTestMethodCallbacks(statement, testInstance, frameworkMethod.getMethod(), testContextManager); } /** * Wrap the supplied {@link Statement} with a {@code RunPrepareTestInstanceCallbacks} statement. * @see RunPrepareTestInstanceCallbacks */ - protected Statement withTestInstancePreparation(Object testInstance, Statement statement) { - return new RunPrepareTestInstanceCallbacks(statement, testInstance, getTestContextManager()); - } - - /** - * Wrap the supplied {@link Statement} with a {@code RunBeforeTestMethodCallbacks} statement. - * @see RunBeforeTestMethodCallbacks - */ - protected Statement withBeforeTestMethodCallbacks(FrameworkMethod frameworkMethod, Object testInstance, - Statement statement) { - return new RunBeforeTestMethodCallbacks(statement, testInstance, frameworkMethod.getMethod(), - getTestContextManager()); - } - - /** - * Wrap the supplied {@link Statement} with a {@code RunAfterTestMethodCallbacks} statement. - * @see RunAfterTestMethodCallbacks - */ - protected Statement withAfterTestMethodCallbacks(FrameworkMethod frameworkMethod, Object testInstance, - Statement statement) { - return new RunAfterTestMethodCallbacks(statement, testInstance, frameworkMethod.getMethod(), - getTestContextManager()); + private Statement withTestInstancePreparation(Statement statement, Object testInstance, + TestContextManager testContextManager) { + return new RunPrepareTestInstanceCallbacks(statement, testInstance, testContextManager); } /** @@ -225,7 +189,7 @@ public class SpringMethodRule implements MethodRule { * @return either a {@code SpringRepeat} or the supplied {@code Statement} * @see SpringRepeat */ - protected Statement withPotentialRepeat(FrameworkMethod frameworkMethod, Object testInstance, Statement next) { + private Statement withPotentialRepeat(Statement next, FrameworkMethod frameworkMethod, Object testInstance) { Repeat repeatAnnotation = AnnotationUtils.getAnnotation(frameworkMethod.getMethod(), Repeat.class); int repeat = (repeatAnnotation != null ? repeatAnnotation.value() : 1); return (repeat > 1 ? new SpringRepeat(next, frameworkMethod.getMethod(), repeat) : next); @@ -243,7 +207,7 @@ public class SpringMethodRule implements MethodRule { * @see #getSpringTimeout(FrameworkMethod) * @see SpringFailOnTimeout */ - protected Statement withPotentialTimeout(FrameworkMethod frameworkMethod, Object testInstance, Statement next) { + private Statement withPotentialTimeout(Statement next, FrameworkMethod frameworkMethod, Object testInstance) { long springTimeout = getSpringTimeout(frameworkMethod); return (springTimeout > 0 ? new SpringFailOnTimeout(next, springTimeout) : next); } @@ -254,7 +218,7 @@ public class SpringMethodRule implements MethodRule { * {@linkplain FrameworkMethod test method}. * @return the timeout, or {@code 0} if none was specified */ - protected long getSpringTimeout(FrameworkMethod frameworkMethod) { + private long getSpringTimeout(FrameworkMethod frameworkMethod) { AnnotationAttributes annAttrs = AnnotatedElementUtils.findAnnotationAttributes(frameworkMethod.getMethod(), Timed.class.getName()); if (annAttrs == null) { @@ -266,29 +230,42 @@ public class SpringMethodRule implements MethodRule { } } - private static SpringClassRule retrieveAndValidateSpringClassRule(Class testClass) { - Field springClassRuleField = null; + /** + * Wrap the supplied {@link Statement} with a {@code ProfileValueChecker} statement. + * @see ProfileValueChecker + */ + private Statement withProfileValueCheck(Statement statement, FrameworkMethod frameworkMethod, Object testInstance) { + return new ProfileValueChecker(statement, testInstance.getClass(), frameworkMethod.getMethod()); + } + + /** + * Throw an {@link IllegalStateException} if the supplied {@code testClass} + * does not declare a {@code public static final SpringClassRule} field + * that is annotated with {@code @ClassRule}. + */ + private static final SpringClassRule validateSpringClassRuleConfiguration(Class testClass) { + Field ruleField = null; for (Field field : testClass.getFields()) { - if (ReflectionUtils.isPublicStaticFinal(field) && (SpringClassRule.class.isAssignableFrom(field.getType()))) { - springClassRuleField = field; + if (ReflectionUtils.isPublicStaticFinal(field) && SpringClassRule.class.isAssignableFrom(field.getType())) { + ruleField = field; break; } } - if (springClassRuleField == null) { + if (ruleField == null) { throw new IllegalStateException(String.format( "Failed to find 'public static final SpringClassRule' field in test class [%s]. " + "Consult the Javadoc for SpringClassRule for details.", testClass.getName())); } - if (!springClassRuleField.isAnnotationPresent(ClassRule.class)) { + if (!ruleField.isAnnotationPresent(ClassRule.class)) { throw new IllegalStateException(String.format( "SpringClassRule field [%s] must be annotated with JUnit's @ClassRule annotation. " - + "Consult the Javadoc for SpringClassRule for details.", springClassRuleField)); + + "Consult the Javadoc for SpringClassRule for details.", ruleField)); } - return (SpringClassRule) ReflectionUtils.getField(springClassRuleField, null); + return (SpringClassRule) ReflectionUtils.getField(ruleField, null); } } diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/BaseAppCtxRuleTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/BaseAppCtxRuleTests.java index 628fc5f0be3..54bf4f6e35e 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/BaseAppCtxRuleTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/BaseAppCtxRuleTests.java @@ -43,29 +43,28 @@ import static org.junit.Assert.*; @ContextConfiguration public class BaseAppCtxRuleTests { - @Configuration - static class Config { - - @Bean - public String foo() { - return "foo"; - } - } - - @ClassRule public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); @Rule - public final SpringMethodRule springMethodRule = new SpringMethodRule(this); + public final SpringMethodRule springMethodRule = new SpringMethodRule(); @Autowired - String foo; + private String foo; @Test - public void test() { + public void foo() { assertEquals("foo", foo); } + + @Configuration + static class Config { + + @Bean + public String foo() { + return "foo"; + } + } } diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/BasicAnnotationConfigWacSpringRuleTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/BasicAnnotationConfigWacSpringRuleTests.java index 8b714cd0e23..2a2c0247ff9 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/BasicAnnotationConfigWacSpringRuleTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/BasicAnnotationConfigWacSpringRuleTests.java @@ -40,6 +40,6 @@ public class BasicAnnotationConfigWacSpringRuleTests extends BasicAnnotationConf public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); @Rule - public final SpringMethodRule springMethodRule = new SpringMethodRule(this); + public final SpringMethodRule springMethodRule = new SpringMethodRule(); } diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/BeforeAndAfterTransactionAnnotationSpringRuleTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/BeforeAndAfterTransactionAnnotationSpringRuleTests.java index e936a0fba10..f5c9aced19b 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/BeforeAndAfterTransactionAnnotationSpringRuleTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/BeforeAndAfterTransactionAnnotationSpringRuleTests.java @@ -38,7 +38,7 @@ public class BeforeAndAfterTransactionAnnotationSpringRuleTests extends BeforeAn public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); @Rule - public final SpringMethodRule springMethodRule = new SpringMethodRule(this); + public final SpringMethodRule springMethodRule = new SpringMethodRule(); // All tests are in superclass. diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/ClassLevelDisabledSpringRuleTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/ClassLevelDisabledSpringRuleTests.java index e8fb3d4ea53..d9f494228e9 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/ClassLevelDisabledSpringRuleTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/ClassLevelDisabledSpringRuleTests.java @@ -38,7 +38,7 @@ public class ClassLevelDisabledSpringRuleTests extends ClassLevelDisabledSpringR public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); @Rule - public final SpringMethodRule springMethodRule = new SpringMethodRule(this); + public final SpringMethodRule springMethodRule = new SpringMethodRule(); // All tests are in superclass. diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/EnabledAndIgnoredSpringRuleTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/EnabledAndIgnoredSpringRuleTests.java index 234569e7fc9..2916adc75a3 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/EnabledAndIgnoredSpringRuleTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/EnabledAndIgnoredSpringRuleTests.java @@ -38,7 +38,7 @@ public class EnabledAndIgnoredSpringRuleTests extends EnabledAndIgnoredSpringRun public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); @Rule - public final SpringMethodRule springMethodRule = new SpringMethodRule(this); + public final SpringMethodRule springMethodRule = new SpringMethodRule(); // All tests are in superclass. diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/FailingBeforeAndAfterMethodsSpringRuleTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/FailingBeforeAndAfterMethodsSpringRuleTests.java index 6fa933bd708..aae85f1c261 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/FailingBeforeAndAfterMethodsSpringRuleTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/FailingBeforeAndAfterMethodsSpringRuleTests.java @@ -76,7 +76,7 @@ public class FailingBeforeAndAfterMethodsSpringRuleTests extends FailingBeforeAn public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); @Rule - public final SpringMethodRule springMethodRule = new SpringMethodRule(this); + public final SpringMethodRule springMethodRule = new SpringMethodRule(); @Test @@ -119,7 +119,7 @@ public class FailingBeforeAndAfterMethodsSpringRuleTests extends FailingBeforeAn public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); @Rule - public final SpringMethodRule springMethodRule = new SpringMethodRule(this); + public final SpringMethodRule springMethodRule = new SpringMethodRule(); @Test @@ -142,7 +142,7 @@ public class FailingBeforeAndAfterMethodsSpringRuleTests extends FailingBeforeAn public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); @Rule - public final SpringMethodRule springMethodRule = new SpringMethodRule(this); + public final SpringMethodRule springMethodRule = new SpringMethodRule(); @Test diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/ParameterizedSpringRuleTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/ParameterizedSpringRuleTests.java index 862ea065a19..bd33cd7cbdb 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/ParameterizedSpringRuleTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/ParameterizedSpringRuleTests.java @@ -55,7 +55,7 @@ public class ParameterizedSpringRuleTests { public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); @Rule - public final SpringMethodRule springMethodRule = new SpringMethodRule(this); + public final SpringMethodRule springMethodRule = new SpringMethodRule(); @Autowired private ApplicationContext applicationContext; diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/ProgrammaticTxMgmtSpringRuleTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/ProgrammaticTxMgmtSpringRuleTests.java index 524b3e22c51..bdb6aa831dc 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/ProgrammaticTxMgmtSpringRuleTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/ProgrammaticTxMgmtSpringRuleTests.java @@ -47,7 +47,7 @@ public class ProgrammaticTxMgmtSpringRuleTests extends ProgrammaticTxMgmtTests { public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); @Rule - public final SpringMethodRule springMethodRule = new SpringMethodRule(this); + public final SpringMethodRule springMethodRule = new SpringMethodRule(); // All tests are in superclass. diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/RepeatedSpringRuleTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/RepeatedSpringRuleTests.java index 37ef1e512df..59b6872faf4 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/RepeatedSpringRuleTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/RepeatedSpringRuleTests.java @@ -76,7 +76,7 @@ public class RepeatedSpringRuleTests extends RepeatedSpringRunnerTests { public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); @Rule - public final SpringMethodRule springMethodRule = new SpringMethodRule(this); + public final SpringMethodRule springMethodRule = new SpringMethodRule(); protected void incrementInvocationCount() throws IOException { diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/Subclass1AppCtxRuleTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/Subclass1AppCtxRuleTests.java index 1f2e4955f9e..23d55a4076b 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/Subclass1AppCtxRuleTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/Subclass1AppCtxRuleTests.java @@ -16,14 +16,40 @@ package org.springframework.test.context.junit4.rules; +import org.junit.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +import static org.junit.Assert.*; + /** * Subclass #1 of {@link BaseAppCtxRuleTests}. * * @author Sam Brannen * @since 4.2 */ +@ContextConfiguration public class Subclass1AppCtxRuleTests extends BaseAppCtxRuleTests { - // All tests and config are in superclass. + @Autowired + private String bar; + + + @Test + public void bar() { + assertEquals("bar", bar); + } + + + @Configuration + static class Config { + @Bean + public String bar() { + return "bar"; + } + } } diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/Subclass2AppCtxRuleTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/Subclass2AppCtxRuleTests.java index 9d277be11ae..6b67f2d8c73 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/Subclass2AppCtxRuleTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/Subclass2AppCtxRuleTests.java @@ -16,14 +16,40 @@ package org.springframework.test.context.junit4.rules; +import org.junit.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; + +import static org.junit.Assert.*; + /** * Subclass #2 of {@link BaseAppCtxRuleTests}. * * @author Sam Brannen * @since 4.2 */ +@ContextConfiguration public class Subclass2AppCtxRuleTests extends BaseAppCtxRuleTests { - // All tests and config are in superclass. + @Autowired + private String baz; + + + @Test + public void baz() { + assertEquals("baz", baz); + } + + + @Configuration + static class Config { + @Bean + public String baz() { + return "baz"; + } + } } diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/TimedSpringRuleTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/TimedSpringRuleTests.java index 6fd12d4830a..5d28391364d 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/TimedSpringRuleTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/TimedSpringRuleTests.java @@ -58,7 +58,7 @@ public class TimedSpringRuleTests extends TimedSpringRunnerTests { public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); @Rule - public final SpringMethodRule springMethodRule = new SpringMethodRule(this); + public final SpringMethodRule springMethodRule = new SpringMethodRule(); /** diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/TimedTransactionalSpringRuleTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/TimedTransactionalSpringRuleTests.java index ca91af6a6b5..a1045dd9e0c 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/TimedTransactionalSpringRuleTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/TimedTransactionalSpringRuleTests.java @@ -45,7 +45,7 @@ public class TimedTransactionalSpringRuleTests extends TimedTransactionalSpringR public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); @Rule - public final SpringMethodRule springMethodRule = new SpringMethodRule(this); + public final SpringMethodRule springMethodRule = new SpringMethodRule(); @Rule public Timeout timeout = Timeout.builder().withTimeout(10, TimeUnit.SECONDS).build(); diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/TransactionalSqlScriptsSpringRuleTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/TransactionalSqlScriptsSpringRuleTests.java index d6506f0259e..d0c736a8878 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/rules/TransactionalSqlScriptsSpringRuleTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/TransactionalSqlScriptsSpringRuleTests.java @@ -49,7 +49,7 @@ public class TransactionalSqlScriptsSpringRuleTests extends TransactionalSqlScri public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule(); @Rule - public final SpringMethodRule springMethodRule = new SpringMethodRule(this); + public final SpringMethodRule springMethodRule = new SpringMethodRule(); @Rule public Timeout timeout = Timeout.builder().withTimeout(10, TimeUnit.SECONDS).build();