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();