diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/PropertiesBasedSpringJUnit4ClassRunnerAppCtxTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/PropertiesBasedSpringJUnit4ClassRunnerAppCtxTests.java new file mode 100644 index 0000000000000000000000000000000000000000..32c07858f28c07b7d248591bb0c7fdbb06d63ddb --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/PropertiesBasedSpringJUnit4ClassRunnerAppCtxTests.java @@ -0,0 +1,77 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.context.junit4; + +import java.util.Properties; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.support.GenericPropertiesContextLoader; +import org.springframework.tests.sample.beans.Pet; + +import static org.junit.Assert.*; + +/** + *
+ * JUnit 4 based test class, which verifies the expected functionality of + * {@link SpringRunner} in conjunction with support for application contexts + * loaded from Java {@link Properties} files. Specifically, the + * {@link ContextConfiguration#loader() loader} attribute of {@code ContextConfiguration} + * and the + * {@link org.springframework.test.context.support.GenericPropertiesContextLoader#getResourceSuffix() + * resourceSuffix} property of {@code GenericPropertiesContextLoader} are tested. + *
+ *+ * Since no {@link ContextConfiguration#locations() locations} are explicitly defined, the + * {@code resourceSuffix} is set to "-context.properties", and since default + * resource locations will be detected by default, this test class's dependencies will be + * injected via {@link Autowired annotation-based autowiring} from beans defined in the + * {@link ApplicationContext} loaded from the default classpath resource: " + * {@code /org/springframework/test/junit4/PropertiesBasedSpringJUnit4ClassRunnerAppCtxTests-context.properties} + * ". + *
+ * + * @author Sam Brannen + * @since 2.5 + * @see GenericPropertiesContextLoader + * @see SpringJUnit4ClassRunnerAppCtxTests + */ +@RunWith(SpringRunner.class) +@ContextConfiguration(loader = GenericPropertiesContextLoader.class) +public class PropertiesBasedSpringJUnit4ClassRunnerAppCtxTests { + + @Autowired + private Pet cat; + + @Autowired + private String testString; + + + @Test + public void verifyAnnotationAutowiredFields() { + assertNotNull("The cat field should have been autowired.", this.cat); + assertEquals("Garfield", this.cat.getName()); + + assertNotNull("The testString field should have been autowired.", this.testString); + assertEquals("Test String", this.testString); + } + +} diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/RelativePathSpringJUnit4ClassRunnerAppCtxTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/RelativePathSpringJUnit4ClassRunnerAppCtxTests.java new file mode 100644 index 0000000000000000000000000000000000000000..5a64bdab56078ea1998bf4bec002a3e7014bb360 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/RelativePathSpringJUnit4ClassRunnerAppCtxTests.java @@ -0,0 +1,34 @@ +/* + * Copyright 2002-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.context.junit4; + +import org.springframework.test.context.ContextConfiguration; + +/** + * Extension of {@link SpringJUnit4ClassRunnerAppCtxTests}, which verifies that + * we can specify an explicit, relative path location for our + * application context. + * + * @author Sam Brannen + * @since 2.5 + * @see SpringJUnit4ClassRunnerAppCtxTests + * @see AbsolutePathSpringJUnit4ClassRunnerAppCtxTests + */ +@ContextConfiguration(locations = { "SpringJUnit4ClassRunnerAppCtxTests-context.xml" }) +public class RelativePathSpringJUnit4ClassRunnerAppCtxTests extends SpringJUnit4ClassRunnerAppCtxTests { + /* all tests are in the parent class. */ +} diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/RepeatedSpringRunnerTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/RepeatedSpringRunnerTests.java new file mode 100644 index 0000000000000000000000000000000000000000..a53fb1854b7d59aac3a9b4e89c00de49135a17a0 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/RepeatedSpringRunnerTests.java @@ -0,0 +1,197 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.context.junit4; + +import java.io.IOException; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runner.Runner; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import org.springframework.test.annotation.Repeat; +import org.springframework.test.annotation.Timed; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.util.ClassUtils; + +import static org.junit.Assert.*; +import static org.springframework.test.context.junit4.JUnitTestingUtils.*; + +/** + * Verifies proper handling of the following in conjunction with the + * {@link SpringRunner}: + *Since no application context resource + * {@link ContextConfiguration#locations() locations} are explicitly declared + * and since the {@link ContextConfiguration#loader() ContextLoader} is left set + * to the default value of {@link GenericXmlContextLoader}, this test class's + * dependencies will be injected via {@link Autowired @Autowired}, + * {@link Inject @Inject}, and {@link Resource @Resource} from beans defined in + * the {@link ApplicationContext} loaded from the default classpath resource: + * {@value #DEFAULT_CONTEXT_RESOURCE_PATH}. + * + * @author Sam Brannen + * @since 2.5 + * @see AbsolutePathSpringJUnit4ClassRunnerAppCtxTests + * @see RelativePathSpringJUnit4ClassRunnerAppCtxTests + * @see InheritedConfigSpringJUnit4ClassRunnerAppCtxTests + */ +@RunWith(SpringRunner.class) +@ContextConfiguration +@TestExecutionListeners(DependencyInjectionTestExecutionListener.class) +public class SpringJUnit4ClassRunnerAppCtxTests implements ApplicationContextAware, BeanNameAware, InitializingBean { + + /** + * Default resource path for the application context configuration for + * {@link SpringJUnit4ClassRunnerAppCtxTests}: {@value #DEFAULT_CONTEXT_RESOURCE_PATH} + */ + public static final String DEFAULT_CONTEXT_RESOURCE_PATH = + "/org/springframework/test/context/junit4/SpringJUnit4ClassRunnerAppCtxTests-context.xml"; + + + private Employee employee; + + @Autowired + private Pet autowiredPet; + + @Inject + private Pet injectedPet; + + @Autowired(required = false) + protected Long nonrequiredLong; + + @Resource + protected String foo; + + protected String bar; + + @Value("enigma") + private String literalFieldValue; + + @Value("#{2 == (1+1)}") + private Boolean spelFieldValue; + + private String literalParameterValue; + + private Boolean spelParameterValue; + + @Autowired + @Qualifier("quux") + protected String quux; + + @Inject + @Named("quux") + protected String namedQuux; + + private String beanName; + + private ApplicationContext applicationContext; + + private boolean beanInitialized = false; + + + @Autowired + protected void setEmployee(Employee employee) { + this.employee = employee; + } + + @Resource + protected void setBar(String bar) { + this.bar = bar; + } + + @Autowired + public void setLiteralParameterValue(@Value("enigma") String literalParameterValue) { + this.literalParameterValue = literalParameterValue; + } + + @Autowired + public void setSpelParameterValue(@Value("#{2 == (1+1)}") Boolean spelParameterValue) { + this.spelParameterValue = spelParameterValue; + } + + @Override + public void setBeanName(String beanName) { + this.beanName = beanName; + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + @Override + public void afterPropertiesSet() { + this.beanInitialized = true; + } + + + @Test + public void verifyBeanNameSet() { + assertTrue("The bean name of this test instance should have been set due to BeanNameAware semantics.", + this.beanName.startsWith(getClass().getName())); + } + + @Test + public void verifyApplicationContextSet() { + assertNotNull("The application context should have been set due to ApplicationContextAware semantics.", + this.applicationContext); + } + + @Test + public void verifyBeanInitialized() { + assertTrue("This test bean should have been initialized due to InitializingBean semantics.", + this.beanInitialized); + } + + @Test + public void verifyAnnotationAutowiredAndInjectedFields() { + assertNull("The nonrequiredLong field should NOT have been autowired.", this.nonrequiredLong); + assertEquals("The quux field should have been autowired via @Autowired and @Qualifier.", "Quux", this.quux); + assertEquals("The namedFoo field should have been injected via @Inject and @Named.", "Quux", this.namedQuux); + assertSame("@Autowired/@Qualifier and @Inject/@Named quux should be the same object.", this.quux, this.namedQuux); + + assertNotNull("The pet field should have been autowired.", this.autowiredPet); + assertNotNull("The pet field should have been injected.", this.injectedPet); + assertEquals("Fido", this.autowiredPet.getName()); + assertEquals("Fido", this.injectedPet.getName()); + assertSame("@Autowired and @Inject pet should be the same object.", this.autowiredPet, this.injectedPet); + } + + @Test + public void verifyAnnotationAutowiredMethods() { + assertNotNull("The employee setter method should have been autowired.", this.employee); + assertEquals("John Smith", this.employee.getName()); + } + + @Test + public void verifyAutowiredAtValueFields() { + assertNotNull("Literal @Value field should have been autowired", this.literalFieldValue); + assertNotNull("SpEL @Value field should have been autowired.", this.spelFieldValue); + assertEquals("enigma", this.literalFieldValue); + assertEquals(Boolean.TRUE, this.spelFieldValue); + } + + @Test + public void verifyAutowiredAtValueMethods() { + assertNotNull("Literal @Value method parameter should have been autowired.", this.literalParameterValue); + assertNotNull("SpEL @Value method parameter should have been autowired.", this.spelParameterValue); + assertEquals("enigma", this.literalParameterValue); + assertEquals(Boolean.TRUE, this.spelParameterValue); + } + + @Test + public void verifyResourceAnnotationInjectedFields() { + assertEquals("The foo field should have been injected via @Resource.", "Foo", this.foo); + } + + @Test + public void verifyResourceAnnotationInjectedMethods() { + assertEquals("The bar method should have been wired via @Resource.", "Bar", this.bar); + } + +} diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunnerTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunnerTests.java new file mode 100644 index 0000000000000000000000000000000000000000..563594ff4250c755ebad23e6d9631f95d1b33f1a --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunnerTests.java @@ -0,0 +1,99 @@ +/* + * Copyright 2002-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.context.junit4; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import org.junit.Test; +import org.junit.runners.model.FrameworkMethod; + +import org.springframework.test.annotation.Timed; +import org.springframework.test.context.TestContextManager; + +import static org.junit.Assert.*; + +/** + * Unit tests for {@link SpringJUnit4ClassRunner}. + * + * @author Sam Brannen + * @author Rick Evans + * @since 2.5 + */ +public class SpringJUnit4ClassRunnerTests { + + @Test(expected = Exception.class) + public void checkThatExceptionsAreNotSilentlySwallowed() throws Exception { + SpringJUnit4ClassRunner runner = new SpringJUnit4ClassRunner(getClass()) { + + @Override + protected TestContextManager createTestContextManager(Class> clazz) { + return new TestContextManager(clazz) { + + @Override + public void prepareTestInstance(Object testInstance) { + throw new RuntimeException( + "This RuntimeException should be caught and wrapped in an Exception."); + } + }; + } + }; + runner.createTest(); + } + + @Test + public void getSpringTimeoutViaMetaAnnotation() throws Exception { + SpringJUnit4ClassRunner runner = new SpringJUnit4ClassRunner(getClass()); + long timeout = runner.getSpringTimeout(new FrameworkMethod(getClass().getDeclaredMethod( + "springTimeoutWithMetaAnnotation"))); + assertEquals(10, timeout); + } + + @Test + public void getSpringTimeoutViaMetaAnnotationWithOverride() throws Exception { + SpringJUnit4ClassRunner runner = new SpringJUnit4ClassRunner(getClass()); + long timeout = runner.getSpringTimeout(new FrameworkMethod(getClass().getDeclaredMethod( + "springTimeoutWithMetaAnnotationAndOverride"))); + assertEquals(42, timeout); + } + + // ------------------------------------------------------------------------- + + @MetaTimed + void springTimeoutWithMetaAnnotation() { + /* no-op */ + } + + @MetaTimedWithOverride(millis = 42) + void springTimeoutWithMetaAnnotationAndOverride() { + /* no-op */ + } + + + @Timed(millis = 10) + @Retention(RetentionPolicy.RUNTIME) + private static @interface MetaTimed { + } + + @Timed(millis = 1000) + @Retention(RetentionPolicy.RUNTIME) + private static @interface MetaTimedWithOverride { + + long millis() default 1000; + } + +} diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4TestSuite.java b/spring-test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4TestSuite.java new file mode 100644 index 0000000000000000000000000000000000000000..994f349624eca77ccf88e14b66e4fe362b04028f --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4TestSuite.java @@ -0,0 +1,119 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.context.junit4; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; +import org.springframework.test.context.cache.ClassLevelDirtiesContextTests; +import org.springframework.test.context.cache.SpringRunnerContextCacheTests; +import org.springframework.test.context.jdbc.IsolatedTransactionModeSqlScriptsTests; +import org.springframework.test.context.junit4.annotation.AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests; +import org.springframework.test.context.junit4.annotation.BeanOverridingDefaultConfigClassesInheritedTests; +import org.springframework.test.context.junit4.annotation.BeanOverridingExplicitConfigClassesInheritedTests; +import org.springframework.test.context.junit4.annotation.DefaultConfigClassesBaseTests; +import org.springframework.test.context.junit4.annotation.DefaultConfigClassesInheritedTests; +import org.springframework.test.context.junit4.annotation.DefaultLoaderBeanOverridingDefaultConfigClassesInheritedTests; +import org.springframework.test.context.junit4.annotation.DefaultLoaderBeanOverridingExplicitConfigClassesInheritedTests; +import org.springframework.test.context.junit4.annotation.DefaultLoaderDefaultConfigClassesBaseTests; +import org.springframework.test.context.junit4.annotation.DefaultLoaderDefaultConfigClassesInheritedTests; +import org.springframework.test.context.junit4.annotation.DefaultLoaderExplicitConfigClassesBaseTests; +import org.springframework.test.context.junit4.annotation.DefaultLoaderExplicitConfigClassesInheritedTests; +import org.springframework.test.context.junit4.annotation.ExplicitConfigClassesBaseTests; +import org.springframework.test.context.junit4.annotation.ExplicitConfigClassesInheritedTests; +import org.springframework.test.context.junit4.orm.HibernateSessionFlushingTests; +import org.springframework.test.context.junit4.profile.annotation.DefaultProfileAnnotationConfigTests; +import org.springframework.test.context.junit4.profile.annotation.DevProfileAnnotationConfigTests; +import org.springframework.test.context.junit4.profile.annotation.DevProfileResolverAnnotationConfigTests; +import org.springframework.test.context.junit4.profile.xml.DefaultProfileXmlConfigTests; +import org.springframework.test.context.junit4.profile.xml.DevProfileResolverXmlConfigTests; +import org.springframework.test.context.junit4.profile.xml.DevProfileXmlConfigTests; +import org.springframework.test.context.transaction.programmatic.ProgrammaticTxMgmtTests; + +/** + * JUnit test suite for tests involving {@link SpringRunner} and the + * Spring TestContext Framework; only intended to be run manually as a + * convenience. + * + *
This test suite serves a dual purpose of verifying that tests run with + * {@link SpringRunner} can be used in conjunction with JUnit's + * {@link Suite} runner. + * + *
Note that tests included in this suite will be executed at least twice if + * run from an automated build process, test runner, etc. that is not configured + * to exclude tests based on a {@code "*TestSuite.class"} pattern match. + * + * @author Sam Brannen + * @since 2.5 + */ +@RunWith(Suite.class) +// Note: the following 'multi-line' layout is for enhanced code readability. +@SuiteClasses({// +StandardJUnit4FeaturesTests.class,// + StandardJUnit4FeaturesSpringRunnerTests.class,// + SpringJUnit47ClassRunnerRuleTests.class,// + AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests.class,// + DefaultConfigClassesBaseTests.class,// + DefaultConfigClassesInheritedTests.class,// + BeanOverridingDefaultConfigClassesInheritedTests.class,// + ExplicitConfigClassesBaseTests.class,// + ExplicitConfigClassesInheritedTests.class,// + BeanOverridingExplicitConfigClassesInheritedTests.class,// + DefaultLoaderDefaultConfigClassesBaseTests.class,// + DefaultLoaderDefaultConfigClassesInheritedTests.class,// + DefaultLoaderBeanOverridingDefaultConfigClassesInheritedTests.class,// + DefaultLoaderExplicitConfigClassesBaseTests.class,// + DefaultLoaderExplicitConfigClassesInheritedTests.class,// + DefaultLoaderBeanOverridingExplicitConfigClassesInheritedTests.class,// + DefaultProfileAnnotationConfigTests.class,// + DevProfileAnnotationConfigTests.class,// + DevProfileResolverAnnotationConfigTests.class,// + DefaultProfileXmlConfigTests.class,// + DevProfileXmlConfigTests.class,// + DevProfileResolverXmlConfigTests.class,// + ExpectedExceptionSpringRunnerTests.class,// + TimedSpringRunnerTests.class,// + RepeatedSpringRunnerTests.class,// + EnabledAndIgnoredSpringRunnerTests.class,// + HardCodedProfileValueSourceSpringRunnerTests.class,// + SpringJUnit4ClassRunnerAppCtxTests.class,// + ClassPathResourceSpringJUnit4ClassRunnerAppCtxTests.class,// + AbsolutePathSpringJUnit4ClassRunnerAppCtxTests.class,// + RelativePathSpringJUnit4ClassRunnerAppCtxTests.class,// + MultipleResourcesSpringJUnit4ClassRunnerAppCtxTests.class,// + InheritedConfigSpringJUnit4ClassRunnerAppCtxTests.class,// + PropertiesBasedSpringJUnit4ClassRunnerAppCtxTests.class,// + CustomDefaultContextLoaderClassSpringRunnerTests.class,// + SpringRunnerContextCacheTests.class,// + ClassLevelDirtiesContextTests.class,// + ParameterizedDependencyInjectionTests.class,// + ConcreteTransactionalJUnit4SpringContextTests.class,// + ClassLevelTransactionalSpringRunnerTests.class,// + MethodLevelTransactionalSpringRunnerTests.class,// + DefaultRollbackTrueRollbackAnnotationTransactionalTests.class,// + DefaultRollbackFalseRollbackAnnotationTransactionalTests.class,// + RollbackOverrideDefaultRollbackTrueTransactionalTests.class,// + RollbackOverrideDefaultRollbackFalseTransactionalTests.class,// + BeforeAndAfterTransactionAnnotationTests.class,// + TimedTransactionalSpringRunnerTests.class,// + ProgrammaticTxMgmtTests.class,// + IsolatedTransactionModeSqlScriptsTests.class,// + HibernateSessionFlushingTests.class // +}) +public class SpringJUnit4TestSuite { + /* this test case consists entirely of tests loaded as a suite. */ +} diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/StandardJUnit4FeaturesSpringRunnerTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/StandardJUnit4FeaturesSpringRunnerTests.java new file mode 100644 index 0000000000000000000000000000000000000000..3390b772a9e08bb28b1280f2d70343d6911cc682 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/StandardJUnit4FeaturesSpringRunnerTests.java @@ -0,0 +1,44 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.context.junit4; + +import org.junit.runner.RunWith; + +import org.springframework.test.context.TestExecutionListeners; + +/** + *
+ * Simple unit test to verify that {@link SpringRunner} does not + * hinder correct functionality of standard JUnit 4.4+ testing features. + *
+ *+ * Note that {@link TestExecutionListeners @TestExecutionListeners} is + * explicitly configured with an empty list, thus disabling all default + * listeners. + *
+ * + * @author Sam Brannen + * @since 2.5 + * @see StandardJUnit4FeaturesTests + */ +@RunWith(SpringRunner.class) +@TestExecutionListeners({}) +public class StandardJUnit4FeaturesSpringRunnerTests extends StandardJUnit4FeaturesTests { + + /* All tests are in the parent class... */ + +} diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/StandardJUnit4FeaturesTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/StandardJUnit4FeaturesTests.java new file mode 100644 index 0000000000000000000000000000000000000000..03344d6069541b79b879cfd52d7865ce48431847 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/StandardJUnit4FeaturesTests.java @@ -0,0 +1,106 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.context.junit4; + +import java.util.ArrayList; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.junit.Assume.*; + +/** + * Simple unit test to verify the expected functionality of standard JUnit 4.4+ + * testing features. + *+ * Currently testing: {@link Test @Test} (including expected exceptions and + * timeouts), {@link BeforeClass @BeforeClass}, {@link Before @Before}, and + * assumptions. + *
+ *+ * Due to the fact that JUnit does not guarantee a particular ordering of test + * method execution, the following are currently not tested: + * {@link org.junit.AfterClass @AfterClass} and {@link org.junit.After @After}. + *
+ * + * @author Sam Brannen + * @since 2.5 + * @see StandardJUnit4FeaturesSpringRunnerTests + */ +public class StandardJUnit4FeaturesTests { + + private static int staticBeforeCounter = 0; + + + @BeforeClass + public static void incrementStaticBeforeCounter() { + StandardJUnit4FeaturesTests.staticBeforeCounter++; + } + + + private int beforeCounter = 0; + + + @Test + @Ignore + public void alwaysFailsButShouldBeIgnored() { + fail("The body of an ignored test should never be executed!"); + } + + @Test + public void alwaysSucceeds() { + assertTrue(true); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void expectingAnIndexOutOfBoundsException() { + new ArrayList<>().get(1); + } + + @Test + public void failedAssumptionShouldPrecludeImminentFailure() { + assumeTrue(false); + fail("A failed assumption should preclude imminent failure!"); + } + + @Before + public void incrementBeforeCounter() { + this.beforeCounter++; + } + + @Test(timeout = 10000) + public void noOpShouldNotTimeOut() { + /* no-op */ + } + + @Test + public void verifyBeforeAnnotation() { + assertEquals(1, this.beforeCounter); + } + + @Test + public void verifyBeforeClassAnnotation() { + // Instead of testing for equality to 1, we just assert that the value + // was incremented at least once, since this test class may serve as a + // parent class to other tests in a suite, etc. + assertTrue(StandardJUnit4FeaturesTests.staticBeforeCounter > 0); + } + +} diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/TimedSpringRunnerTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/TimedSpringRunnerTests.java new file mode 100644 index 0000000000000000000000000000000000000000..82931405d097d18ffcd5e60dfb5f7078e1cdc7bd --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/TimedSpringRunnerTests.java @@ -0,0 +1,124 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.context.junit4; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runner.Runner; +import org.junit.runners.JUnit4; + +import org.springframework.test.annotation.Timed; +import org.springframework.test.context.TestExecutionListeners; + +import static org.springframework.test.context.junit4.JUnitTestingUtils.*; + +/** + * Verifies proper handling of the following in conjunction with the + * {@link SpringRunner}: + *This class has been implemented in response to the following Stack Overflow question:
+ *
+ * Can {@code @ContextConfiguration} in a custom annotation be merged?
+ *
+ * @author Sam Brannen
+ * @since 4.3
+ */
+@RunWith(SpringRunner.class)
+@ComposedContextConfiguration(BarConfig.class)
+public class InitializerConfiguredViaMetaAnnotationTests {
+
+ @Autowired
+ String foo;
+
+ @Autowired
+ String bar;
+
+ @Autowired
+ List Furthermore, by extending {@link SpringJUnit4ClassRunnerAppCtxTests},
+ * this class also verifies support for several basic features of the
+ * Spring TestContext Framework. See JavaDoc in
+ * {@code SpringJUnit4ClassRunnerAppCtxTests} for details.
+ *
+ * Configuration will be loaded from {@link PojoAndStringConfig}.
+ *
+ * @author Sam Brannen
+ * @since 3.1
+ */
+@ContextConfiguration(classes = PojoAndStringConfig.class, inheritLocations = false)
+public class AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests extends SpringJUnit4ClassRunnerAppCtxTests {
+ /* all tests are in the parent class. */
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigTestSuite.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigTestSuite.java
new file mode 100644
index 0000000000000000000000000000000000000000..f5f16ea9937186ee5ca5f3d24221a1c601fbc6d5
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigTestSuite.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2002-2011 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * JUnit test suite for annotation-driven configuration class
+ * support in the Spring TestContext Framework.
+ *
+ * @author Sam Brannen
+ * @since 3.1
+ */
+@RunWith(Suite.class)
+// Note: the following 'multi-line' layout is for enhanced code readability.
+@SuiteClasses({//
+AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests.class,//
+ DefaultConfigClassesBaseTests.class,//
+ DefaultConfigClassesInheritedTests.class,//
+ BeanOverridingDefaultConfigClassesInheritedTests.class,//
+ ExplicitConfigClassesBaseTests.class,//
+ ExplicitConfigClassesInheritedTests.class,//
+ BeanOverridingExplicitConfigClassesInheritedTests.class,//
+ DefaultLoaderDefaultConfigClassesBaseTests.class,//
+ DefaultLoaderDefaultConfigClassesInheritedTests.class,//
+ DefaultLoaderBeanOverridingDefaultConfigClassesInheritedTests.class,//
+ DefaultLoaderExplicitConfigClassesBaseTests.class,//
+ DefaultLoaderExplicitConfigClassesInheritedTests.class,//
+ DefaultLoaderBeanOverridingExplicitConfigClassesInheritedTests.class //
+})
+public class AnnotationConfigTestSuite {
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/BeanOverridingDefaultConfigClassesInheritedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/BeanOverridingDefaultConfigClassesInheritedTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..7e517f68b8ff389ff89bd6995e6b7c5913560e3c
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/BeanOverridingDefaultConfigClassesInheritedTests.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation;
+
+import org.junit.Test;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.tests.sample.beans.Employee;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify support for configuration classes in
+ * the Spring TestContext Framework.
+ *
+ * Configuration will be loaded from {@link DefaultConfigClassesBaseTests.ContextConfiguration}
+ * and {@link BeanOverridingDefaultConfigClassesInheritedTests.ContextConfiguration}.
+ *
+ * @author Sam Brannen
+ * @since 3.1
+ */
+@ContextConfiguration
+public class BeanOverridingDefaultConfigClassesInheritedTests extends DefaultConfigClassesBaseTests {
+
+ @Configuration
+ static class ContextConfiguration {
+
+ @Bean
+ public Employee employee() {
+ Employee employee = new Employee();
+ employee.setName("Yoda");
+ employee.setAge(900);
+ employee.setCompany("The Force");
+ return employee;
+ }
+ }
+
+
+ @Test
+ @Override
+ public void verifyEmployeeSetFromBaseContextConfig() {
+ assertNotNull("The employee should have been autowired.", this.employee);
+ assertEquals("The employee bean should have been overridden.", "Yoda", this.employee.getName());
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/BeanOverridingExplicitConfigClassesInheritedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/BeanOverridingExplicitConfigClassesInheritedTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..b60421dd53ffb3f863165cad613a1d57f6430c55
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/BeanOverridingExplicitConfigClassesInheritedTests.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation;
+
+import org.junit.Test;
+
+import org.springframework.test.context.ContextConfiguration;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify support for configuration classes in
+ * the Spring TestContext Framework.
+ *
+ * Configuration will be loaded from {@link DefaultConfigClassesBaseTests.ContextConfiguration}
+ * and {@link BeanOverridingDefaultConfigClassesInheritedTests.ContextConfiguration}.
+ *
+ * @author Sam Brannen
+ * @since 3.1
+ */
+@ContextConfiguration(classes = BeanOverridingDefaultConfigClassesInheritedTests.ContextConfiguration.class)
+public class BeanOverridingExplicitConfigClassesInheritedTests extends ExplicitConfigClassesBaseTests {
+
+ @Test
+ @Override
+ public void verifyEmployeeSetFromBaseContextConfig() {
+ assertNotNull("The employee should have been autowired.", this.employee);
+ assertEquals("The employee bean should have been overridden.", "Yoda", this.employee.getName());
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultConfigClassesBaseTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultConfigClassesBaseTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..c9d45dbb5768b7aa85a22eaa4aab7c79e85462b0
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultConfigClassesBaseTests.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+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 org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+import org.springframework.tests.sample.beans.Employee;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify support for configuration classes in
+ * the Spring TestContext Framework.
+ *
+ * Configuration will be loaded from {@link DefaultConfigClassesBaseTests.ContextConfiguration}.
+ *
+ * @author Sam Brannen
+ * @since 3.1
+ * @see DefaultLoaderDefaultConfigClassesBaseTests
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
+public class DefaultConfigClassesBaseTests {
+
+ @Configuration
+ static class ContextConfiguration {
+
+ @Bean
+ public Employee employee() {
+ Employee employee = new Employee();
+ employee.setName("John Smith");
+ employee.setAge(42);
+ employee.setCompany("Acme Widgets, Inc.");
+ return employee;
+ }
+ }
+
+
+ @Autowired
+ protected Employee employee;
+
+
+ @Test
+ public void verifyEmployeeSetFromBaseContextConfig() {
+ assertNotNull("The employee field should have been autowired.", this.employee);
+ assertEquals("John Smith", this.employee.getName());
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultConfigClassesInheritedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultConfigClassesInheritedTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca35da919ea6de7e3f2be73480453a0e07d596c0
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultConfigClassesInheritedTests.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation;
+
+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 org.springframework.tests.sample.beans.Pet;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify support for configuration classes in
+ * the Spring TestContext Framework.
+ *
+ * Configuration will be loaded from {@link DefaultConfigClassesBaseTests.ContextConfiguration}
+ * and {@link DefaultConfigClassesInheritedTests.ContextConfiguration}.
+ *
+ * @author Sam Brannen
+ * @since 3.1
+ */
+@ContextConfiguration
+public class DefaultConfigClassesInheritedTests extends DefaultConfigClassesBaseTests {
+
+ @Configuration
+ static class ContextConfiguration {
+
+ @Bean
+ public Pet pet() {
+ return new Pet("Fido");
+ }
+ }
+
+
+ @Autowired
+ private Pet pet;
+
+
+ @Test
+ public void verifyPetSetFromExtendedContextConfig() {
+ assertNotNull("The pet should have been autowired.", this.pet);
+ assertEquals("Fido", this.pet.getName());
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderBeanOverridingDefaultConfigClassesInheritedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderBeanOverridingDefaultConfigClassesInheritedTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..23c6dd4e8c2b9f3b14508017fcc7148ca7e63ce9
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderBeanOverridingDefaultConfigClassesInheritedTests.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation;
+
+import org.junit.Test;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.support.DelegatingSmartContextLoader;
+import org.springframework.tests.sample.beans.Employee;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify support for configuration classes in
+ * the Spring TestContext Framework in conjunction with the
+ * {@link DelegatingSmartContextLoader}.
+ *
+ * @author Sam Brannen
+ * @since 3.1
+ */
+@ContextConfiguration
+public class DefaultLoaderBeanOverridingDefaultConfigClassesInheritedTests extends
+ DefaultLoaderDefaultConfigClassesBaseTests {
+
+ @Configuration
+ static class Config {
+
+ @Bean
+ public Employee employee() {
+ Employee employee = new Employee();
+ employee.setName("Yoda");
+ employee.setAge(900);
+ employee.setCompany("The Force");
+ return employee;
+ }
+ }
+
+
+ @Test
+ @Override
+ public void verifyEmployeeSetFromBaseContextConfig() {
+ assertNotNull("The employee should have been autowired.", this.employee);
+ assertEquals("The employee bean should have been overridden.", "Yoda", this.employee.getName());
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderBeanOverridingExplicitConfigClassesInheritedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderBeanOverridingExplicitConfigClassesInheritedTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..de79c131ebd44d64e2a82db263a56864fe22a7ba
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderBeanOverridingExplicitConfigClassesInheritedTests.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation;
+
+import org.junit.Test;
+
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.support.DelegatingSmartContextLoader;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify support for configuration classes in
+ * the Spring TestContext Framework in conjunction with the
+ * {@link DelegatingSmartContextLoader}.
+ *
+ * @author Sam Brannen
+ * @since 3.1
+ */
+@ContextConfiguration(classes = DefaultLoaderBeanOverridingDefaultConfigClassesInheritedTests.Config.class)
+public class DefaultLoaderBeanOverridingExplicitConfigClassesInheritedTests extends
+ DefaultLoaderExplicitConfigClassesBaseTests {
+
+ @Test
+ @Override
+ public void verifyEmployeeSetFromBaseContextConfig() {
+ assertNotNull("The employee should have been autowired.", this.employee);
+ assertEquals("The employee bean should have been overridden.", "Yoda", this.employee.getName());
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderDefaultConfigClassesBaseTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderDefaultConfigClassesBaseTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..5c738d7efb42f7044821d3df9ccbec4c6ab64ec5
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderDefaultConfigClassesBaseTests.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+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 org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.DelegatingSmartContextLoader;
+import org.springframework.tests.sample.beans.Employee;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify support for configuration classes in
+ * the Spring TestContext Framework in conjunction with the
+ * {@link DelegatingSmartContextLoader}.
+ *
+ * @author Sam Brannen
+ * @since 3.1
+ * @see DefaultConfigClassesBaseTests
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration
+public class DefaultLoaderDefaultConfigClassesBaseTests {
+
+ @Configuration
+ static class Config {
+
+ @Bean
+ public Employee employee() {
+ Employee employee = new Employee();
+ employee.setName("John Smith");
+ employee.setAge(42);
+ employee.setCompany("Acme Widgets, Inc.");
+ return employee;
+ }
+ }
+
+
+ @Autowired
+ protected Employee employee;
+
+
+ @Test
+ public void verifyEmployeeSetFromBaseContextConfig() {
+ assertNotNull("The employee field should have been autowired.", this.employee);
+ assertEquals("John Smith", this.employee.getName());
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderDefaultConfigClassesInheritedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderDefaultConfigClassesInheritedTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..05eabe5d77a0bc9f7ef5b5004c3eae34512fc72d
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderDefaultConfigClassesInheritedTests.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation;
+
+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 org.springframework.test.context.support.DelegatingSmartContextLoader;
+import org.springframework.tests.sample.beans.Pet;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify support for configuration classes in
+ * the Spring TestContext Framework in conjunction with the
+ * {@link DelegatingSmartContextLoader}.
+ *
+ * @author Sam Brannen
+ * @since 3.1
+ */
+@ContextConfiguration
+public class DefaultLoaderDefaultConfigClassesInheritedTests extends DefaultLoaderDefaultConfigClassesBaseTests {
+
+ @Configuration
+ static class Config {
+
+ @Bean
+ public Pet pet() {
+ return new Pet("Fido");
+ }
+ }
+
+
+ @Autowired
+ private Pet pet;
+
+
+ @Test
+ public void verifyPetSetFromExtendedContextConfig() {
+ assertNotNull("The pet should have been autowired.", this.pet);
+ assertEquals("Fido", this.pet.getName());
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderExplicitConfigClassesBaseTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderExplicitConfigClassesBaseTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..feec6a94e3c3aa011a45a759865989a351648e6f
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderExplicitConfigClassesBaseTests.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.DelegatingSmartContextLoader;
+import org.springframework.tests.sample.beans.Employee;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify support for configuration classes in
+ * the Spring TestContext Framework in conjunction with the
+ * {@link DelegatingSmartContextLoader}.
+ *
+ * @author Sam Brannen
+ * @since 3.1
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = DefaultLoaderDefaultConfigClassesBaseTests.Config.class)
+public class DefaultLoaderExplicitConfigClassesBaseTests {
+
+ @Autowired
+ protected Employee employee;
+
+
+ @Test
+ public void verifyEmployeeSetFromBaseContextConfig() {
+ assertNotNull("The employee should have been autowired.", this.employee);
+ assertEquals("John Smith", this.employee.getName());
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderExplicitConfigClassesInheritedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderExplicitConfigClassesInheritedTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..5cdec6353d2d06924c9ada368aaa0dd8cd3591fe
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultLoaderExplicitConfigClassesInheritedTests.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.DelegatingSmartContextLoader;
+import org.springframework.tests.sample.beans.Pet;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify support for configuration classes in
+ * the Spring TestContext Framework in conjunction with the
+ * {@link DelegatingSmartContextLoader}.
+ *
+ * @author Sam Brannen
+ * @since 3.1
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = DefaultLoaderDefaultConfigClassesInheritedTests.Config.class)
+public class DefaultLoaderExplicitConfigClassesInheritedTests extends DefaultLoaderExplicitConfigClassesBaseTests {
+
+ @Autowired
+ private Pet pet;
+
+
+ @Test
+ public void verifyPetSetFromExtendedContextConfig() {
+ assertNotNull("The pet should have been autowired.", this.pet);
+ assertEquals("Fido", this.pet.getName());
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/ExplicitConfigClassesBaseTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/ExplicitConfigClassesBaseTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..cc6d56ba689145b2f0a983fd48ac2b61c8b2bdd3
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/ExplicitConfigClassesBaseTests.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+import org.springframework.tests.sample.beans.Employee;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify support for configuration classes in
+ * the Spring TestContext Framework.
+ *
+ * Configuration will be loaded from {@link DefaultConfigClassesBaseTests.ContextConfiguration}.
+ *
+ * @author Sam Brannen
+ * @since 3.1
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = DefaultConfigClassesBaseTests.ContextConfiguration.class)
+public class ExplicitConfigClassesBaseTests {
+
+ @Autowired
+ protected Employee employee;
+
+
+ @Test
+ public void verifyEmployeeSetFromBaseContextConfig() {
+ assertNotNull("The employee should have been autowired.", this.employee);
+ assertEquals("John Smith", this.employee.getName());
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/ExplicitConfigClassesInheritedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/ExplicitConfigClassesInheritedTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..1cebcca22da3a6123790562114126674a9be119e
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/ExplicitConfigClassesInheritedTests.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+import org.springframework.tests.sample.beans.Pet;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify support for configuration classes in
+ * the Spring TestContext Framework.
+ *
+ * Configuration will be loaded from {@link DefaultConfigClassesInheritedTests.ContextConfiguration}
+ * and {@link DefaultConfigClassesBaseTests.ContextConfiguration}.
+ *
+ * @author Sam Brannen
+ * @since 3.1
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = DefaultConfigClassesInheritedTests.ContextConfiguration.class)
+public class ExplicitConfigClassesInheritedTests extends ExplicitConfigClassesBaseTests {
+
+ @Autowired
+ private Pet pet;
+
+
+ @Test
+ public void verifyPetSetFromExtendedContextConfig() {
+ assertNotNull("The pet should have been autowired.", this.pet);
+ assertEquals("Fido", this.pet.getName());
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/PojoAndStringConfig.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/PojoAndStringConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..fab6e51dbf47ff3776a393db85f9373d83c19cd6
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/PojoAndStringConfig.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.tests.sample.beans.Employee;
+import org.springframework.tests.sample.beans.Pet;
+
+/**
+ * ApplicationContext configuration class for various integration tests.
+ *
+ * The beans defined in this configuration class map directly to the
+ * beans defined in {@code SpringJUnit4ClassRunnerAppCtxTests-context.xml}.
+ * Consequently, the application contexts loaded from these two sources
+ * should be identical with regard to bean definitions.
+ *
+ * @author Sam Brannen
+ * @since 3.1
+ */
+@Configuration
+public class PojoAndStringConfig {
+
+ @Bean
+ public Employee employee() {
+ Employee employee = new Employee();
+ employee.setName("John Smith");
+ employee.setAge(42);
+ employee.setCompany("Acme Widgets, Inc.");
+ return employee;
+ }
+
+ @Bean
+ public Pet pet() {
+ return new Pet("Fido");
+ }
+
+ @Bean
+ public String foo() {
+ return "Foo";
+ }
+
+ @Bean
+ public String bar() {
+ return "Bar";
+ }
+
+ @Bean
+ public String quux() {
+ return "Quux";
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..e084468e39bbf9f8aa6a6af216c508feb08f933d
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2002-2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation.meta;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.ActiveProfilesResolver;
+import org.springframework.test.context.ContextConfiguration;
+
+/**
+ * Custom configuration annotation with meta-annotation attribute overrides for
+ * {@link ContextConfiguration#classes} and {@link ActiveProfiles#resolver} and
+ * with default configuration local to the composed annotation.
+ *
+ * @author Sam Brannen
+ * @since 4.0.3
+ */
+@ContextConfiguration
+@ActiveProfiles
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig {
+
+ @Configuration
+ @Profile("dev")
+ static class DevConfig {
+
+ @Bean
+ public String foo() {
+ return "Dev Foo";
+ }
+ }
+
+ @Configuration
+ @Profile("prod")
+ static class ProductionConfig {
+
+ @Bean
+ public String foo() {
+ return "Production Foo";
+ }
+ }
+
+ @Configuration
+ @Profile("resolver")
+ static class ResolverConfig {
+
+ @Bean
+ public String foo() {
+ return "Resolver Foo";
+ }
+ }
+
+ static class CustomResolver implements ActiveProfilesResolver {
+
+ @Override
+ public String[] resolve(Class> testClass) {
+ return testClass.getSimpleName().equals("ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigTests") ? new String[] { "resolver" }
+ : new String[] {};
+ }
+ }
+
+
+ Class>[] classes() default { DevConfig.class, ProductionConfig.class, ResolverConfig.class };
+
+ Class extends ActiveProfilesResolver> resolver() default CustomResolver.class;
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..d14534829242968b337900d6bf1cfd6c86742408
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigTests.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2002-2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation.meta;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests for meta-annotation attribute override support, relying on
+ * default attribute values defined in {@link ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig}.
+ *
+ * @author Sam Brannen
+ * @since 4.0.3
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig
+public class ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigTests {
+
+ @Autowired
+ private String foo;
+
+
+ @Test
+ public void foo() {
+ assertEquals("Resolver Foo", foo);
+ }
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigWithOverridesTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigWithOverridesTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..20515d9b998b8dcfb5b172593b92fc7857da4edd
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigWithOverridesTests.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2002-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation.meta;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.test.context.ActiveProfilesResolver;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests for meta-annotation attribute override support, overriding
+ * default attribute values defined in {@link ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig}.
+ *
+ * @author Sam Brannen
+ * @since 4.0.3
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig(classes = LocalDevConfig.class, resolver = DevResolver.class)
+public class ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigWithOverridesTests {
+
+ @Autowired
+ private String foo;
+
+
+ @Test
+ public void foo() {
+ assertEquals("Local Dev Foo", foo);
+ }
+}
+
+@Configuration
+@Profile("dev")
+class LocalDevConfig {
+
+ @Bean
+ public String foo() {
+ return "Local Dev Foo";
+ }
+}
+
+class DevResolver implements ActiveProfilesResolver {
+
+ @Override
+ public String[] resolve(Class> testClass) {
+ // Checking that the "test class" name ends with "*Tests" ensures that an actual
+ // test class is passed to this method as opposed to a "*Config" class which would
+ // imply that we likely have been passed the 'declaringClass' instead of the
+ // 'rootDeclaringClass'.
+ return testClass.getName().endsWith("Tests") ? new String[] { "dev" } : new String[] {};
+ }
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesMetaConfig.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesMetaConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..cbba94088998156504aea65ba60e78ebb8cd4e46
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesMetaConfig.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2002-2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation.meta;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.ContextConfiguration;
+
+/**
+ * Custom configuration annotation with meta-annotation attribute overrides for
+ * {@link ContextConfiguration#classes} and {@link ActiveProfiles#profiles} and
+ * no default configuration local to the composed annotation.
+ *
+ * @author Sam Brannen
+ * @since 4.0.3
+ */
+@ContextConfiguration
+@ActiveProfiles
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ConfigClassesAndProfilesMetaConfig {
+
+ Class>[] classes() default {};
+
+ String[] profiles() default {};
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesMetaConfigTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesMetaConfigTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..0b5c2df10c5cd6ccb4099022a1f185ccb80ac429
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesMetaConfigTests.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2002-2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation.meta;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests for meta-annotation attribute override support, demonstrating
+ * that the test class is used as the declaring class when detecting default
+ * configuration classes for the declaration of {@code @ContextConfiguration}.
+ *
+ * @author Sam Brannen
+ * @since 4.0.3
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ConfigClassesAndProfilesMetaConfig(profiles = "dev")
+public class ConfigClassesAndProfilesMetaConfigTests {
+
+ @Configuration
+ @Profile("dev")
+ static class DevConfig {
+
+ @Bean
+ public String foo() {
+ return "Local Dev Foo";
+ }
+ }
+
+ @Configuration
+ @Profile("prod")
+ static class ProductionConfig {
+
+ @Bean
+ public String foo() {
+ return "Local Production Foo";
+ }
+ }
+
+
+ @Autowired
+ private String foo;
+
+
+ @Test
+ public void foo() {
+ assertEquals("Local Dev Foo", foo);
+ }
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfig.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..b953200f5de21514d0d78c20d0d50978bd540b8b
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfig.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2002-2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation.meta;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.ContextConfiguration;
+
+/**
+ * Custom configuration annotation with meta-annotation attribute overrides for
+ * {@link ContextConfiguration#classes} and {@link ActiveProfiles#profiles} and
+ * with default configuration local to the composed annotation.
+ *
+ * @author Sam Brannen
+ * @since 4.0
+ */
+@ContextConfiguration
+@ActiveProfiles
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ConfigClassesAndProfilesWithCustomDefaultsMetaConfig {
+
+ @Configuration
+ @Profile("dev")
+ static class DevConfig {
+
+ @Bean
+ public String foo() {
+ return "Dev Foo";
+ }
+ }
+
+ @Configuration
+ @Profile("prod")
+ static class ProductionConfig {
+
+ @Bean
+ public String foo() {
+ return "Production Foo";
+ }
+ }
+
+
+ Class>[] classes() default { DevConfig.class, ProductionConfig.class };
+
+ String[] profiles() default "dev";
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfigTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfigTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..096716529832df807c25726a3e465812fa030d0a
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfigTests.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2002-2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation.meta;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests for meta-annotation attribute override support, relying on
+ * default attribute values defined in {@link ConfigClassesAndProfilesWithCustomDefaultsMetaConfig}.
+ *
+ * @author Sam Brannen
+ * @since 4.0
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ConfigClassesAndProfilesWithCustomDefaultsMetaConfig
+public class ConfigClassesAndProfilesWithCustomDefaultsMetaConfigTests {
+
+ @Autowired
+ private String foo;
+
+
+ @Test
+ public void foo() {
+ assertEquals("Dev Foo", foo);
+ }
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfigWithOverridesTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfigWithOverridesTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..3502f1c92f0a0a7f52b535b9b9f03b50245b733b
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfigWithOverridesTests.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2002-2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation.meta;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.annotation.PojoAndStringConfig;
+import org.springframework.tests.sample.beans.Employee;
+import org.springframework.tests.sample.beans.Pet;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests for meta-annotation attribute override support, overriding
+ * default attribute values defined in {@link ConfigClassesAndProfilesWithCustomDefaultsMetaConfig}.
+ *
+ * @author Sam Brannen
+ * @since 4.0
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ConfigClassesAndProfilesWithCustomDefaultsMetaConfig(classes = { PojoAndStringConfig.class,
+ ConfigClassesAndProfilesWithCustomDefaultsMetaConfig.ProductionConfig.class }, profiles = "prod")
+public class ConfigClassesAndProfilesWithCustomDefaultsMetaConfigWithOverridesTests {
+
+ @Autowired
+ private String foo;
+
+ @Autowired
+ private Pet pet;
+
+ @Autowired
+ protected Employee employee;
+
+
+ @Test
+ public void verifyEmployee() {
+ assertNotNull("The employee should have been autowired.", this.employee);
+ assertEquals("John Smith", this.employee.getName());
+ }
+
+ @Test
+ public void verifyPet() {
+ assertNotNull("The pet should have been autowired.", this.pet);
+ assertEquals("Fido", this.pet.getName());
+ }
+
+ @Test
+ public void verifyFoo() {
+ assertEquals("Production Foo", this.foo);
+ }
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaMetaConfig.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaMetaConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..be59c1119f024433d0a7e3149aa1f726f7f812af
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaMetaConfig.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2002-2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation.meta;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.test.context.ActiveProfiles;
+
+/**
+ * Custom configuration annotation that is itself meta-annotated with {@link
+ * ConfigClassesAndProfilesWithCustomDefaultsMetaConfig} and {@link ActiveProfiles}.
+ *
+ * @author Sam Brannen
+ * @since 4.0.3
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@ConfigClassesAndProfilesWithCustomDefaultsMetaConfig
+// Override default "dev" profile from
+// @ConfigClassesAndProfilesWithCustomDefaultsMetaConfig:
+@ActiveProfiles("prod")
+public @interface MetaMetaConfig {
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaMetaConfigDefaultsTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaMetaConfigDefaultsTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..3d2e60ee9c20e4e44e2656db69aac2934557da84
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaMetaConfigDefaultsTests.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2002-2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.annotation.meta;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests for meta-meta-annotation support, relying on default attribute
+ * values defined in {@link ConfigClassesAndProfilesWithCustomDefaultsMetaConfig} and
+ * overrides in {@link MetaMetaConfig}.
+ *
+ * @author Sam Brannen
+ * @since 4.0.3
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@MetaMetaConfig
+public class MetaMetaConfigDefaultsTests {
+
+ @Autowired
+ private String foo;
+
+
+ @Test
+ public void foo() {
+ assertEquals("Production Foo", foo);
+ }
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/concurrency/SpringJUnit4ConcurrencyTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/concurrency/SpringJUnit4ConcurrencyTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f8bc9bc9a5bb0c2abe38fd418e890e3e0ffc73d
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/concurrency/SpringJUnit4ConcurrencyTests.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2002-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.concurrency;
+
+import java.lang.annotation.Annotation;
+import java.util.Arrays;
+
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.experimental.ParallelComputer;
+
+import org.springframework.test.context.hierarchies.web.DispatcherWacRootWacEarTests;
+import org.springframework.test.context.junit4.InheritedConfigSpringJUnit4ClassRunnerAppCtxTests;
+import org.springframework.test.context.junit4.MethodLevelTransactionalSpringRunnerTests;
+import org.springframework.test.context.junit4.SpringJUnit47ClassRunnerRuleTests;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunnerAppCtxTests;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.junit4.TimedTransactionalSpringRunnerTests;
+import org.springframework.test.context.junit4.rules.BaseAppCtxRuleTests;
+import org.springframework.test.context.junit4.rules.BasicAnnotationConfigWacSpringRuleTests;
+import org.springframework.test.context.junit4.rules.SpringClassRule;
+import org.springframework.test.context.junit4.rules.SpringMethodRule;
+import org.springframework.test.context.web.RequestAndSessionScopedBeansWacTests;
+import org.springframework.test.context.web.socket.WebSocketServletServerContainerFactoryBeanTests;
+import org.springframework.test.web.client.samples.SampleTests;
+import org.springframework.test.web.servlet.samples.context.JavaConfigTests;
+import org.springframework.test.web.servlet.samples.context.WebAppResourceTests;
+import org.springframework.tests.Assume;
+import org.springframework.tests.TestGroup;
+import org.springframework.util.ReflectionUtils;
+
+import static org.springframework.core.annotation.AnnotatedElementUtils.*;
+import static org.springframework.test.context.junit4.JUnitTestingUtils.*;
+
+/**
+ * Concurrency tests for the {@link SpringRunner}, {@link SpringClassRule}, and
+ * {@link SpringMethodRule} that use JUnit 4's experimental {@link ParallelComputer}
+ * to execute tests in parallel.
+ *
+ * The tests executed by this test class come from a hand-picked collection of test
+ * classes within the test suite that is intended to cover most categories of tests
+ * that are currently supported by the TestContext Framework on JUnit 4.
+ *
+ * The chosen test classes intentionally do not include any classes that
+ * fall under the following categories.
+ *
+ * NOTE: these tests only run if the {@link TestGroup#LONG_RUNNING
+ * LONG_RUNNING} test group is enabled.
+ *
+ * @author Sam Brannen
+ * @since 5.0
+ * @see org.springframework.test.context.TestContextConcurrencyTests
+ */
+public class SpringJUnit4ConcurrencyTests {
+
+ private final Class>[] testClasses = new Class>[] {
+ // Basics
+ SpringJUnit4ClassRunnerAppCtxTests.class,
+ InheritedConfigSpringJUnit4ClassRunnerAppCtxTests.class,
+ SpringJUnit47ClassRunnerRuleTests.class,
+ BaseAppCtxRuleTests.class,
+ // Transactional
+ MethodLevelTransactionalSpringRunnerTests.class,
+ TimedTransactionalSpringRunnerTests.class,
+ // Web and Scopes
+ DispatcherWacRootWacEarTests.class,
+ BasicAnnotationConfigWacSpringRuleTests.class,
+ RequestAndSessionScopedBeansWacTests.class,
+ WebSocketServletServerContainerFactoryBeanTests.class,
+ // Spring MVC Test
+ JavaConfigTests.class,
+ WebAppResourceTests.class,
+ SampleTests.class
+ };
+
+
+ @BeforeClass
+ public static void abortIfLongRunningTestGroupIsNotEnabled() {
+ Assume.group(TestGroup.LONG_RUNNING);
+ }
+
+ @Test
+ public void runAllTestsConcurrently() throws Exception {
+ final int FAILED = 0;
+ final int ABORTED = 0;
+ final int IGNORED = countAnnotatedMethods(Ignore.class);
+ final int TESTS = countAnnotatedMethods(Test.class) - IGNORED;
+
+ runTestsAndAssertCounters(new ParallelComputer(true, true), TESTS, FAILED, TESTS, IGNORED, ABORTED,
+ this.testClasses);
+ }
+
+ private int countAnnotatedMethods(Class extends Annotation> annotationType) {
+ return (int) Arrays.stream(this.testClasses)
+ .map(ReflectionUtils::getUniqueDeclaredMethods)
+ .flatMap(Arrays::stream)
+ .filter(method -> hasAnnotation(method, annotationType))
+ .count();
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/hybrid/HybridContextLoader.java b/spring-test/src/test/java/org/springframework/test/context/junit4/hybrid/HybridContextLoader.java
new file mode 100644
index 0000000000000000000000000000000000000000..02f74de9b8a8f1f9662bf464b0fdee26dea65579
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/hybrid/HybridContextLoader.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2002-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.hybrid;
+
+import org.springframework.beans.factory.support.BeanDefinitionReader;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
+import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.test.context.ContextConfigurationAttributes;
+import org.springframework.test.context.MergedContextConfiguration;
+import org.springframework.test.context.SmartContextLoader;
+import org.springframework.test.context.support.AbstractGenericContextLoader;
+import org.springframework.util.Assert;
+
+import static org.springframework.test.context.support.AnnotationConfigContextLoaderUtils.*;
+
+/**
+ * Hybrid {@link SmartContextLoader} that supports path-based and class-based
+ * resources simultaneously.
+ * This test loader is inspired by Spring Boot.
+ * Detects defaults for XML configuration and annotated classes.
+ * Beans from XML configuration always override those from annotated classes.
+ *
+ * @author Sam Brannen
+ * @since 4.0.4
+ */
+public class HybridContextLoader extends AbstractGenericContextLoader {
+
+ @Override
+ protected void validateMergedContextConfiguration(MergedContextConfiguration mergedConfig) {
+ Assert.isTrue(mergedConfig.hasClasses() || mergedConfig.hasLocations(), getClass().getSimpleName()
+ + " requires either classes or locations");
+ }
+
+ @Override
+ public void processContextConfiguration(ContextConfigurationAttributes configAttributes) {
+ // Detect default XML configuration files:
+ super.processContextConfiguration(configAttributes);
+
+ // Detect default configuration classes:
+ if (!configAttributes.hasClasses() && isGenerateDefaultLocations()) {
+ configAttributes.setClasses(detectDefaultConfigurationClasses(configAttributes.getDeclaringClass()));
+ }
+ }
+
+ @Override
+ protected void loadBeanDefinitions(GenericApplicationContext context, MergedContextConfiguration mergedConfig) {
+ // Order doesn't matter: The goal of this class and its subclasses is to ensure that Rule-based
+ * configuration can be inherited without requiring {@link SpringClassRule}
+ * or {@link SpringMethodRule} to be redeclared on subclasses.
+ *
+ * @author Sam Brannen
+ * @since 4.2
+ * @see Subclass1AppCtxRuleTests
+ * @see Subclass2AppCtxRuleTests
+ */
+@ContextConfiguration
+public class BaseAppCtxRuleTests {
+
+ @ClassRule
+ public static final SpringClassRule springClassRule = new SpringClassRule();
+
+ @Rule
+ public final SpringMethodRule springMethodRule = new SpringMethodRule();
+
+ @Autowired
+ private String foo;
+
+
+ @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
new file mode 100644
index 0000000000000000000000000000000000000000..8c2f26f8fda4eaa66a960b08c9966cd659d2ec02
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/BasicAnnotationConfigWacSpringRuleTests.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2002-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.rules;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import org.springframework.test.context.web.BasicAnnotationConfigWacTests;
+
+/**
+ * This class is an extension of {@link BasicAnnotationConfigWacTests}
+ * that has been modified to use {@link SpringClassRule} and
+ * {@link SpringMethodRule}.
+ *
+ * @author Sam Brannen
+ * @since 4.2
+ */
+@RunWith(JUnit4.class)
+public class BasicAnnotationConfigWacSpringRuleTests extends BasicAnnotationConfigWacTests {
+
+ // All tests are in superclass.
+
+ @ClassRule
+ public static final SpringClassRule springClassRule = new SpringClassRule();
+
+ @Rule
+ 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
new file mode 100644
index 0000000000000000000000000000000000000000..bff96a6fe8dbe7958516f58a1ae3009fba217f3b
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/BeforeAndAfterTransactionAnnotationSpringRuleTests.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2002-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.rules;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import org.springframework.test.context.junit4.BeforeAndAfterTransactionAnnotationTests;
+
+/**
+ * This class is an extension of {@link BeforeAndAfterTransactionAnnotationTests}
+ * that has been modified to use {@link SpringClassRule} and
+ * {@link SpringMethodRule}.
+ *
+ * @author Sam Brannen
+ * @since 4.2
+ */
+@RunWith(JUnit4.class)
+public class BeforeAndAfterTransactionAnnotationSpringRuleTests extends BeforeAndAfterTransactionAnnotationTests {
+
+ @ClassRule
+ public static final SpringClassRule springClassRule = new SpringClassRule();
+
+ @Rule
+ 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
new file mode 100644
index 0000000000000000000000000000000000000000..453a9c7ef2bc5537ba33b2950457cadac48ff2e3
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/ClassLevelDisabledSpringRuleTests.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2002-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.rules;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import org.springframework.test.context.junit4.ClassLevelDisabledSpringRunnerTests;
+
+/**
+ * This class is an extension of {@link ClassLevelDisabledSpringRunnerTests}
+ * that has been modified to use {@link SpringClassRule} and
+ * {@link SpringMethodRule}.
+ *
+ * @author Sam Brannen
+ * @since 4.2
+ */
+@RunWith(JUnit4.class)
+public class ClassLevelDisabledSpringRuleTests extends ClassLevelDisabledSpringRunnerTests {
+
+ @ClassRule
+ public static final SpringClassRule springClassRule = new SpringClassRule();
+
+ @Rule
+ 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
new file mode 100644
index 0000000000000000000000000000000000000000..27f29eca93d2102fef70d484170789f294321f67
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/EnabledAndIgnoredSpringRuleTests.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2002-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.rules;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import org.springframework.test.context.junit4.EnabledAndIgnoredSpringRunnerTests;
+
+/**
+ * This class is an extension of {@link EnabledAndIgnoredSpringRunnerTests}
+ * that has been modified to use {@link SpringClassRule} and
+ * {@link SpringMethodRule}.
+ *
+ * @author Sam Brannen
+ * @since 4.2
+ */
+@RunWith(JUnit4.class)
+public class EnabledAndIgnoredSpringRuleTests extends EnabledAndIgnoredSpringRunnerTests {
+
+ @ClassRule
+ public static final SpringClassRule springClassRule = new SpringClassRule();
+
+ @Rule
+ 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
new file mode 100644
index 0000000000000000000000000000000000000000..ff0968c3e3d6fef32046bc6243818b97f9ceb5d7
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/FailingBeforeAndAfterMethodsSpringRuleTests.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2002-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.rules;
+
+import org.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
+import org.junit.runners.JUnit4;
+import org.junit.runners.Parameterized.Parameters;
+
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestExecutionListeners;
+import org.springframework.test.context.junit4.FailingBeforeAndAfterMethodsSpringRunnerTests;
+import org.springframework.test.context.transaction.AfterTransaction;
+import org.springframework.test.context.transaction.BeforeTransaction;
+import org.springframework.transaction.annotation.Transactional;
+
+import static org.junit.Assert.*;
+
+/**
+ * This class is an extension of {@link FailingBeforeAndAfterMethodsSpringRunnerTests}
+ * that has been modified to use {@link SpringClassRule} and
+ * {@link SpringMethodRule}.
+ *
+ * @author Sam Brannen
+ * @since 4.2
+ */
+public class FailingBeforeAndAfterMethodsSpringRuleTests extends FailingBeforeAndAfterMethodsSpringRunnerTests {
+
+ @Parameters(name = "{0}")
+ public static Object[] testData() {
+ return new Object[] {//
+ AlwaysFailingBeforeTestClassSpringRuleTestCase.class.getSimpleName(),//
+ AlwaysFailingAfterTestClassSpringRuleTestCase.class.getSimpleName(),//
+ AlwaysFailingPrepareTestInstanceSpringRuleTestCase.class.getSimpleName(),//
+ AlwaysFailingBeforeTestMethodSpringRuleTestCase.class.getSimpleName(),//
+ AlwaysFailingAfterTestMethodSpringRuleTestCase.class.getSimpleName(),//
+ FailingBeforeTransactionSpringRuleTestCase.class.getSimpleName(),//
+ FailingAfterTransactionSpringRuleTestCase.class.getSimpleName() //
+ };
+ }
+
+ public FailingBeforeAndAfterMethodsSpringRuleTests(String testClassName) throws Exception {
+ super(testClassName);
+ }
+
+ @Override
+ protected Class extends Runner> getRunnerClass() {
+ return JUnit4.class;
+ }
+
+ // All tests are in superclass.
+
+ @RunWith(JUnit4.class)
+ public static abstract class BaseSpringRuleTestCase {
+
+ @ClassRule
+ public static final SpringClassRule springClassRule = new SpringClassRule();
+
+ @Rule
+ public final SpringMethodRule springMethodRule = new SpringMethodRule();
+
+
+ @Test
+ public void testNothing() {
+ }
+ }
+
+ @Ignore("TestCase classes are run manually by the enclosing test class")
+ @TestExecutionListeners(AlwaysFailingBeforeTestClassTestExecutionListener.class)
+ public static class AlwaysFailingBeforeTestClassSpringRuleTestCase extends BaseSpringRuleTestCase {
+ }
+
+ @Ignore("TestCase classes are run manually by the enclosing test class")
+ @TestExecutionListeners(AlwaysFailingAfterTestClassTestExecutionListener.class)
+ public static class AlwaysFailingAfterTestClassSpringRuleTestCase extends BaseSpringRuleTestCase {
+ }
+
+ @Ignore("TestCase classes are run manually by the enclosing test class")
+ @TestExecutionListeners(AlwaysFailingPrepareTestInstanceTestExecutionListener.class)
+ public static class AlwaysFailingPrepareTestInstanceSpringRuleTestCase extends BaseSpringRuleTestCase {
+ }
+
+ @Ignore("TestCase classes are run manually by the enclosing test class")
+ @TestExecutionListeners(AlwaysFailingBeforeTestMethodTestExecutionListener.class)
+ public static class AlwaysFailingBeforeTestMethodSpringRuleTestCase extends BaseSpringRuleTestCase {
+ }
+
+ @Ignore("TestCase classes are run manually by the enclosing test class")
+ @TestExecutionListeners(AlwaysFailingAfterTestMethodTestExecutionListener.class)
+ public static class AlwaysFailingAfterTestMethodSpringRuleTestCase extends BaseSpringRuleTestCase {
+ }
+
+ @Ignore("TestCase classes are run manually by the enclosing test class")
+ @RunWith(JUnit4.class)
+ @ContextConfiguration("../FailingBeforeAndAfterMethodsTests-context.xml")
+ @Transactional
+ public static class FailingBeforeTransactionSpringRuleTestCase {
+
+ @ClassRule
+ public static final SpringClassRule springClassRule = new SpringClassRule();
+
+ @Rule
+ public final SpringMethodRule springMethodRule = new SpringMethodRule();
+
+
+ @Test
+ public void testNothing() {
+ }
+
+ @BeforeTransaction
+ public void beforeTransaction() {
+ fail("always failing beforeTransaction()");
+ }
+ }
+
+ @Ignore("TestCase classes are run manually by the enclosing test class")
+ @RunWith(JUnit4.class)
+ @ContextConfiguration("../FailingBeforeAndAfterMethodsTests-context.xml")
+ @Transactional
+ public static class FailingAfterTransactionSpringRuleTestCase {
+
+ @ClassRule
+ public static final SpringClassRule springClassRule = new SpringClassRule();
+
+ @Rule
+ public final SpringMethodRule springMethodRule = new SpringMethodRule();
+
+
+ @Test
+ public void testNothing() {
+ }
+
+ @AfterTransaction
+ public void afterTransaction() {
+ fail("always failing afterTransaction()");
+ }
+ }
+
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..a0d2dec4e42ecfface4d2c56ec8e945630049a36
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/ParameterizedSpringRuleTests.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2002-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.rules;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.tests.sample.beans.Employee;
+import org.springframework.tests.sample.beans.Pet;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration test which demonstrates how to use JUnit's {@link Parameterized}
+ * runner in conjunction with {@link SpringClassRule} and {@link SpringMethodRule}
+ * to provide dependency injection to a parameterized test instance.
+ *
+ * @author Sam Brannen
+ * @since 4.2
+ * @see org.springframework.test.context.junit4.ParameterizedDependencyInjectionTests
+ */
+@RunWith(Parameterized.class)
+@ContextConfiguration("/org/springframework/test/context/junit4/ParameterizedDependencyInjectionTests-context.xml")
+public class ParameterizedSpringRuleTests {
+
+ private static final AtomicInteger invocationCount = new AtomicInteger();
+
+ @ClassRule
+ public static final SpringClassRule springClassRule = new SpringClassRule();
+
+ @Rule
+ public final SpringMethodRule springMethodRule = new SpringMethodRule();
+
+ @Autowired
+ private ApplicationContext applicationContext;
+
+ @Autowired
+ private Pet pet;
+
+ @Parameter(0)
+ public String employeeBeanName;
+
+ @Parameter(1)
+ public String employeeName;
+
+
+ @Parameters(name = "bean [{0}], employee [{1}]")
+ public static String[][] employeeData() {
+ return new String[][] { { "employee1", "John Smith" }, { "employee2", "Jane Smith" } };
+ }
+
+ @BeforeClass
+ public static void BeforeClass() {
+ invocationCount.set(0);
+ }
+
+ @Test
+ public final void verifyPetAndEmployee() {
+ invocationCount.incrementAndGet();
+
+ // Verifying dependency injection:
+ assertNotNull("The pet field should have been autowired.", this.pet);
+
+ // Verifying 'parameterized' support:
+ Employee employee = this.applicationContext.getBean(this.employeeBeanName, Employee.class);
+ assertEquals("Name of the employee configured as bean [" + this.employeeBeanName + "].", this.employeeName,
+ employee.getName());
+ }
+
+ @AfterClass
+ public static void verifyNumParameterizedRuns() {
+ assertEquals("Number of times the parameterized test method was executed.", employeeData().length,
+ invocationCount.get());
+ }
+
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..8bd5043cfba2375f8112bc0beb32bd48c2e950fa
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/ProgrammaticTxMgmtSpringRuleTests.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2002-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.rules;
+
+import javax.sql.DataSource;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.transaction.programmatic.ProgrammaticTxMgmtTests;
+import org.springframework.transaction.PlatformTransactionManager;
+
+/**
+ * This class is an extension of {@link ProgrammaticTxMgmtTests}
+ * that has been modified to use {@link SpringClassRule} and
+ * {@link SpringMethodRule}.
+ *
+ * @author Sam Brannen
+ * @since 4.2
+ */
+@RunWith(JUnit4.class)
+@ContextConfiguration
+public class ProgrammaticTxMgmtSpringRuleTests extends ProgrammaticTxMgmtTests {
+
+ @ClassRule
+ public static final SpringClassRule springClassRule = new SpringClassRule();
+
+ @Rule
+ public final SpringMethodRule springMethodRule = new SpringMethodRule();
+
+ // All tests are in superclass.
+
+ // -------------------------------------------------------------------------
+
+ @Configuration
+ static class Config {
+
+ @Bean
+ public PlatformTransactionManager transactionManager() {
+ return new DataSourceTransactionManager(dataSource());
+ }
+
+ @Bean
+ public DataSource dataSource() {
+ return new EmbeddedDatabaseBuilder()//
+ .generateUniqueName(true)//
+ .addScript("classpath:/org/springframework/test/context/jdbc/schema.sql") //
+ .build();
+ }
+ }
+
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..d06cdd71015f8cdf1206ec03519bc35f6b444348
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/RepeatedSpringRuleTests.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2002-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.rules;
+
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import org.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.Runner;
+import org.junit.runners.JUnit4;
+import org.junit.runners.Parameterized.Parameters;
+
+import org.springframework.test.annotation.Repeat;
+import org.springframework.test.annotation.Timed;
+import org.springframework.test.context.TestExecutionListeners;
+import org.springframework.test.context.junit4.RepeatedSpringRunnerTests;
+
+/**
+ * This class is an extension of {@link RepeatedSpringRunnerTests}
+ * that has been modified to use {@link SpringClassRule} and
+ * {@link SpringMethodRule}.
+ *
+ * @author Sam Brannen
+ * @since 4.2
+ */
+public class RepeatedSpringRuleTests extends RepeatedSpringRunnerTests {
+
+ @Parameters(name = "{0}")
+ public static Object[][] repetitionData() {
+ return new Object[][] {//
+ { NonAnnotatedRepeatedTestCase.class.getSimpleName(), 0, 1, 1, 1 },//
+ { DefaultRepeatValueRepeatedTestCase.class.getSimpleName(), 0, 1, 1, 1 },//
+ { NegativeRepeatValueRepeatedTestCase.class.getSimpleName(), 0, 1, 1, 1 },//
+ { RepeatedFiveTimesRepeatedTestCase.class.getSimpleName(), 0, 1, 1, 5 },//
+ { RepeatedFiveTimesViaMetaAnnotationRepeatedTestCase.class.getSimpleName(), 0, 1, 1, 5 },//
+ { TimedRepeatedTestCase.class.getSimpleName(), 3, 4, 4, (5 + 1 + 4 + 10) } //
+ };
+ }
+
+ public RepeatedSpringRuleTests(String testClassName, int expectedFailureCount, int expectedTestStartedCount,
+ int expectedTestFinishedCount, int expectedInvocationCount) throws Exception {
+
+ super(testClassName, expectedFailureCount, expectedTestStartedCount, expectedTestFinishedCount,
+ expectedInvocationCount);
+ }
+
+ @Override
+ protected Class extends Runner> getRunnerClass() {
+ return JUnit4.class;
+ }
+
+ // All tests are in superclass.
+
+ @TestExecutionListeners({})
+ public abstract static class AbstractRepeatedTestCase {
+
+ @ClassRule
+ public static final SpringClassRule springClassRule = new SpringClassRule();
+
+ @Rule
+ public final SpringMethodRule springMethodRule = new SpringMethodRule();
+
+
+ protected void incrementInvocationCount() throws IOException {
+ invocationCount.incrementAndGet();
+ }
+ }
+
+ public static final class NonAnnotatedRepeatedTestCase extends AbstractRepeatedTestCase {
+
+ @Test
+ @Timed(millis = 10000)
+ public void nonAnnotated() throws Exception {
+ incrementInvocationCount();
+ }
+ }
+
+ public static final class DefaultRepeatValueRepeatedTestCase extends AbstractRepeatedTestCase {
+
+ @Test
+ @Repeat
+ @Timed(millis = 10000)
+ public void defaultRepeatValue() throws Exception {
+ incrementInvocationCount();
+ }
+ }
+
+ public static final class NegativeRepeatValueRepeatedTestCase extends AbstractRepeatedTestCase {
+
+ @Test
+ @Repeat(-5)
+ @Timed(millis = 10000)
+ public void negativeRepeatValue() throws Exception {
+ incrementInvocationCount();
+ }
+ }
+
+ public static final class RepeatedFiveTimesRepeatedTestCase extends AbstractRepeatedTestCase {
+
+ @Test
+ @Repeat(5)
+ public void repeatedFiveTimes() throws Exception {
+ incrementInvocationCount();
+ }
+ }
+
+ @Repeat(5)
+ @Retention(RetentionPolicy.RUNTIME)
+ private static @interface RepeatedFiveTimes {
+ }
+
+ public static final class RepeatedFiveTimesViaMetaAnnotationRepeatedTestCase extends AbstractRepeatedTestCase {
+
+ @Test
+ @RepeatedFiveTimes
+ public void repeatedFiveTimes() throws Exception {
+ incrementInvocationCount();
+ }
+ }
+
+ /**
+ * Unit tests for claims raised in SPR-6011.
+ */
+ @Ignore("TestCase classes are run manually by the enclosing test class")
+ public static final class TimedRepeatedTestCase extends AbstractRepeatedTestCase {
+
+ @Test
+ @Timed(millis = 1000)
+ @Repeat(5)
+ public void repeatedFiveTimesButDoesNotExceedTimeout() throws Exception {
+ incrementInvocationCount();
+ }
+
+ @Test
+ @Timed(millis = 10)
+ @Repeat(1)
+ public void singleRepetitionExceedsTimeout() throws Exception {
+ incrementInvocationCount();
+ Thread.sleep(15);
+ }
+
+ @Test
+ @Timed(millis = 20)
+ @Repeat(4)
+ public void firstRepetitionOfManyExceedsTimeout() throws Exception {
+ incrementInvocationCount();
+ Thread.sleep(25);
+ }
+
+ @Test
+ @Timed(millis = 100)
+ @Repeat(10)
+ public void collectiveRepetitionsExceedTimeout() throws Exception {
+ incrementInvocationCount();
+ Thread.sleep(11);
+ }
+ }
+
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..3cb915e8b70bdbfbfb3eed55a8a90a0f32fd015e
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/Subclass1AppCtxRuleTests.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2002-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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 {
+
+ @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
new file mode 100644
index 0000000000000000000000000000000000000000..cf43bd2c240bbad6c3d85a744af115e5b106443f
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/Subclass2AppCtxRuleTests.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2002-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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 {
+
+ @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
new file mode 100644
index 0000000000000000000000000000000000000000..802c69b41ead11f1b210cfe44eedae56bead4cfe
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/TimedSpringRuleTests.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2002-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.rules;
+
+import org.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.runner.Runner;
+import org.junit.runners.JUnit4;
+
+import org.springframework.test.context.TestExecutionListeners;
+import org.springframework.test.context.junit4.TimedSpringRunnerTests;
+
+import static org.junit.Assert.*;
+
+/**
+ * This class is an extension of {@link TimedSpringRunnerTests}
+ * that has been modified to use {@link SpringClassRule} and
+ * {@link SpringMethodRule}.
+ *
+ * @author Sam Brannen
+ * @since 4.2
+ */
+public class TimedSpringRuleTests extends TimedSpringRunnerTests {
+
+ // All tests are in superclass.
+
+ @Override
+ protected Class> getTestCase() {
+ return TimedSpringRuleTestCase.class;
+ }
+
+ @Override
+ protected Class extends Runner> getRunnerClass() {
+ return JUnit4.class;
+ }
+
+
+ @Ignore("TestCase classes are run manually by the enclosing test class")
+ @TestExecutionListeners({})
+ public static final class TimedSpringRuleTestCase extends TimedSpringRunnerTestCase {
+
+ @ClassRule
+ public static final SpringClassRule springClassRule = new SpringClassRule();
+
+ @Rule
+ public final SpringMethodRule springMethodRule = new SpringMethodRule();
+
+
+ /**
+ * Overridden to always throw an exception, since Spring's Rule-based
+ * JUnit integration does not fail a test for duplicate configuration
+ * of timeouts.
+ */
+ @Override
+ public void springAndJUnitTimeouts() {
+ fail("intentional failure to make tests in superclass pass");
+ }
+
+ // All other tests are in superclass.
+ }
+
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..105017497b14ffd3fa187af398628dd42cfd2547
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/TimedTransactionalSpringRuleTests.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2002-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.rules;
+
+import java.util.concurrent.TimeUnit;
+
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.Timeout;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import org.springframework.test.annotation.Repeat;
+import org.springframework.test.context.junit4.TimedTransactionalSpringRunnerTests;
+
+import static org.springframework.test.transaction.TransactionTestUtils.*;
+
+/**
+ * This class is an extension of {@link TimedTransactionalSpringRunnerTests}
+ * that has been modified to use {@link SpringClassRule} and
+ * {@link SpringMethodRule}.
+ *
+ * @author Sam Brannen
+ * @since 4.2
+ */
+@RunWith(JUnit4.class)
+public class TimedTransactionalSpringRuleTests extends TimedTransactionalSpringRunnerTests {
+
+ @ClassRule
+ public static final SpringClassRule springClassRule = new SpringClassRule();
+
+ @Rule
+ public final SpringMethodRule springMethodRule = new SpringMethodRule();
+
+ @Rule
+ public Timeout timeout = Timeout.builder().withTimeout(10, TimeUnit.SECONDS).build();
+
+
+ /**
+ * Overridden since Spring's Rule-based JUnit support cannot properly
+ * integrate with timed execution that is controlled by a third-party runner.
+ */
+ @Test(timeout = 10000)
+ @Repeat(5)
+ @Override
+ public void transactionalWithJUnitTimeout() {
+ assertInTransaction(false);
+ }
+
+ /**
+ * {@code timeout} explicitly not declared due to presence of Timeout rule.
+ */
+ @Test
+ public void transactionalWithJUnitRuleBasedTimeout() {
+ assertInTransaction(true);
+ }
+
+ // All other tests are in superclass.
+
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..523a3b36eb0279e3fcbcf530faf2735ebdc1667a
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/rules/TransactionalSqlScriptsSpringRuleTests.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2002-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.rules;
+
+import java.util.concurrent.TimeUnit;
+
+import org.junit.ClassRule;
+import org.junit.FixMethodOrder;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.Timeout;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.junit.runners.MethodSorters;
+
+import org.springframework.test.context.jdbc.Sql;
+import org.springframework.test.context.jdbc.TransactionalSqlScriptsTests;
+
+/**
+ * This class is an extension of {@link TransactionalSqlScriptsTests}
+ * that has been modified to use {@link SpringClassRule} and
+ * {@link SpringMethodRule}.
+ *
+ * @author Sam Brannen
+ * @since 4.2
+ */
+@RunWith(JUnit4.class)
+// Note: @FixMethodOrder is NOT @Inherited.
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+// Overriding @Sql declaration to reference scripts using relative path.
+@Sql({ "../../jdbc/schema.sql", "../../jdbc/data.sql" })
+public class TransactionalSqlScriptsSpringRuleTests extends TransactionalSqlScriptsTests {
+
+ @ClassRule
+ public static final SpringClassRule springClassRule = new SpringClassRule();
+
+ @Rule
+ public final SpringMethodRule springMethodRule = new SpringMethodRule();
+
+ @Rule
+ public Timeout timeout = Timeout.builder().withTimeout(10, TimeUnit.SECONDS).build();
+
+
+ /**
+ * Redeclared to ensure that {@code @FixMethodOrder} is properly applied.
+ */
+ @Test
+ @Override
+ // test##_ prefix is required for @FixMethodOrder.
+ public void test01_classLevelScripts() {
+ assertNumUsers(1);
+ }
+
+ /**
+ * Overriding {@code @Sql} declaration to reference scripts using relative path.
+ */
+ @Test
+ @Sql({ "../../jdbc/drop-schema.sql", "../../jdbc/schema.sql", "../../jdbc/data.sql", "../../jdbc/data-add-dogbert.sql" })
+ @Override
+ // test##_ prefix is required for @FixMethodOrder.
+ public void test02_methodLevelScripts() {
+ assertNumUsers(2);
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/BeanOverridingDefaultLocationsInheritedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/BeanOverridingDefaultLocationsInheritedTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..97274401f0fbf9dfc2b91b144b3afea82b55568b
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/BeanOverridingDefaultLocationsInheritedTests.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr3896;
+
+import org.junit.Test;
+
+import org.springframework.test.context.ContextConfiguration;
+
+import static org.junit.Assert.*;
+
+/**
+ * JUnit 4 based integration test for verifying support for the
+ * {@link ContextConfiguration#inheritLocations() inheritLocations} flag of
+ * {@link ContextConfiguration @ContextConfiguration} indirectly proposed in SPR-3896.
+ *
+ * @author Sam Brannen
+ * @since 2.5
+ */
+@ContextConfiguration
+public class BeanOverridingDefaultLocationsInheritedTests extends DefaultLocationsBaseTests {
+
+ @Test
+ @Override
+ public void verifyEmployeeSetFromBaseContextConfig() {
+ assertNotNull("The employee should have been autowired.", this.employee);
+ assertEquals("The employee bean should have been overridden.", "Yoda", this.employee.getName());
+ }
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/BeanOverridingExplicitLocationsInheritedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/BeanOverridingExplicitLocationsInheritedTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..efd60eadbc36734b88c1c0b0cb13caa315b40fe5
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/BeanOverridingExplicitLocationsInheritedTests.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr3896;
+
+import org.junit.Test;
+
+import org.springframework.test.context.ContextConfiguration;
+
+import static org.junit.Assert.*;
+
+/**
+ * JUnit 4 based integration test for verifying support for the
+ * {@link ContextConfiguration#inheritLocations() inheritLocations} flag of
+ * {@link ContextConfiguration @ContextConfiguration} indirectly proposed in SPR-3896.
+ *
+ * @author Sam Brannen
+ * @since 2.5
+ */
+@ContextConfiguration("BeanOverridingDefaultLocationsInheritedTests-context.xml")
+public class BeanOverridingExplicitLocationsInheritedTests extends ExplicitLocationsBaseTests {
+
+ @Test
+ @Override
+ public void verifyEmployeeSetFromBaseContextConfig() {
+ assertNotNull("The employee should have been autowired.", this.employee);
+ assertEquals("The employee bean should have been overridden.", "Yoda", this.employee.getName());
+ }
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/DefaultLocationsBaseTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/DefaultLocationsBaseTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..d4eb3a0291f871de93490d1fc43f1fa1f8fb4d63
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/DefaultLocationsBaseTests.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr3896;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.tests.sample.beans.Employee;
+
+import static org.junit.Assert.*;
+
+/**
+ * JUnit 4 based integration test for verifying support for the
+ * {@link ContextConfiguration#inheritLocations() inheritLocations} flag of
+ * {@link ContextConfiguration @ContextConfiguration} indirectly proposed in SPR-3896.
+ *
+ * @author Sam Brannen
+ * @since 2.5
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration
+public class DefaultLocationsBaseTests {
+
+ @Autowired
+ protected Employee employee;
+
+
+ @Test
+ public void verifyEmployeeSetFromBaseContextConfig() {
+ assertNotNull("The employee should have been autowired.", this.employee);
+ assertEquals("John Smith", this.employee.getName());
+ }
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/DefaultLocationsInheritedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/DefaultLocationsInheritedTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..a282649a6f4b67bbfc69a1a2de7f959a6ee35c94
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/DefaultLocationsInheritedTests.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr3896;
+
+import org.junit.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.tests.sample.beans.Pet;
+
+import static org.junit.Assert.*;
+
+/**
+ * JUnit 4 based integration test for verifying support for the
+ * {@link ContextConfiguration#inheritLocations() inheritLocations} flag of
+ * {@link ContextConfiguration @ContextConfiguration} indirectly proposed in SPR-3896.
+ *
+ * @author Sam Brannen
+ * @since 2.5
+ */
+@ContextConfiguration
+public class DefaultLocationsInheritedTests extends DefaultLocationsBaseTests {
+
+ @Autowired
+ private Pet pet;
+
+
+ @Test
+ public void verifyPetSetFromExtendedContextConfig() {
+ assertNotNull("The pet should have been autowired.", this.pet);
+ assertEquals("Fido", this.pet.getName());
+ }
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/ExplicitLocationsBaseTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/ExplicitLocationsBaseTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..f3b75c99c966dee22ff534ef7047e20ed343afdf
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/ExplicitLocationsBaseTests.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr3896;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.tests.sample.beans.Employee;
+
+import static org.junit.Assert.*;
+
+/**
+ * JUnit 4 based integration test for verifying support for the
+ * {@link ContextConfiguration#inheritLocations() inheritLocations} flag of
+ * {@link ContextConfiguration @ContextConfiguration} indirectly proposed in SPR-3896.
+ *
+ * @author Sam Brannen
+ * @since 2.5
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("DefaultLocationsBaseTests-context.xml")
+public class ExplicitLocationsBaseTests {
+
+ @Autowired
+ protected Employee employee;
+
+
+ @Test
+ public void verifyEmployeeSetFromBaseContextConfig() {
+ assertNotNull("The employee should have been autowired.", this.employee);
+ assertEquals("John Smith", this.employee.getName());
+ }
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/ExplicitLocationsInheritedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/ExplicitLocationsInheritedTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f3da5a432dab81ba3ec24c1cdd006c93312f820
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/ExplicitLocationsInheritedTests.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr3896;
+
+import org.junit.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.tests.sample.beans.Pet;
+
+import static org.junit.Assert.*;
+
+/**
+ * JUnit 4 based integration test for verifying support for the
+ * {@link ContextConfiguration#inheritLocations() inheritLocations} flag of
+ * {@link ContextConfiguration @ContextConfiguration} indirectly proposed in SPR-3896.
+ *
+ * @author Sam Brannen
+ * @since 2.5
+ */
+@ContextConfiguration("DefaultLocationsInheritedTests-context.xml")
+public class ExplicitLocationsInheritedTests extends ExplicitLocationsBaseTests {
+
+ @Autowired
+ private Pet pet;
+
+
+ @Test
+ public void verifyPetSetFromExtendedContextConfig() {
+ assertNotNull("The pet should have been autowired.", this.pet);
+ assertEquals("Fido", this.pet.getName());
+ }
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/Spr3896SuiteTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/Spr3896SuiteTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..2e9b6e9cbb2ce48b14a44c0715ff3acf56a132ff
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr3896/Spr3896SuiteTests.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2002-2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr3896;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * JUnit 4 based test suite for functionality proposed in SPR-3896.
+ *
+ * @author Sam Brannen
+ * @since 2.5
+ */
+@RunWith(Suite.class)
+// Note: the following 'multi-line' layout is for enhanced code readability.
+@SuiteClasses({
+
+DefaultLocationsBaseTests.class,
+
+DefaultLocationsInheritedTests.class,
+
+ExplicitLocationsBaseTests.class,
+
+ExplicitLocationsInheritedTests.class,
+
+BeanOverridingDefaultLocationsInheritedTests.class,
+
+BeanOverridingExplicitLocationsInheritedTests.class
+
+})
+public class Spr3896SuiteTests {
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr4868/Jsr250LifecycleTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr4868/Jsr250LifecycleTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..e968a97f314ec630ab64dc68786bc7e2c65290b9
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr4868/Jsr250LifecycleTests.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2002-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr4868;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+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 org.springframework.test.context.TestExecutionListeners;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that investigate the applicability of JSR-250 lifecycle
+ * annotations in test classes.
+ *
+ * This class does not really contain actual tests per se. Rather it
+ * can be used to empirically verify the expected log output (see below). In
+ * order to see the log output, one would naturally need to ensure that the
+ * logger category for this class is enabled at {@code INFO} level.
+ *
+ * By using a SpEL expression to generate a random {@code database-name}
+ * for the embedded database (see {@code datasource-config.xml}), we ensure
+ * that each {@code ApplicationContext} that imports the common configuration
+ * will create an embedded database with a unique name.
+ *
+ * To reproduce the problem mentioned in SPR-8849, delete the declaration
+ * of the {@code database-name} attribute of the embedded database in
+ * {@code datasource-config.xml} and run this suite.
+ *
+ * As of Spring 4.2, a proper solution is possible thanks to SPR-8849.
+ * {@link TestClass3} and {@link TestClass4} both import
+ * {@code datasource-config-with-auto-generated-db-name.xml} which makes
+ * use of the new {@code generate-name} attribute of {@code The Claims:
+ *
+ * Consequently, this class contains standard singleton bean methods
+ * instead of annotated factory bean methods.
+ */
+ @Configuration
+ static class Config {
+
+ @Bean
+ public Employee employee() {
+ Employee employee = new Employee();
+ employee.setName("John Smith");
+ employee.setAge(42);
+ employee.setCompany("Acme Widgets, Inc.");
+ return employee;
+ }
+
+ @Bean
+ public PlatformTransactionManager transactionManager() {
+ return new DataSourceTransactionManager(dataSource());
+ }
+
+ @Bean
+ public DataSource dataSource() {
+ return new EmbeddedDatabaseBuilder()//
+ .addScript("classpath:/org/springframework/test/jdbc/schema.sql")//
+ // Ensure that this in-memory database is only used by this class:
+ .setName(getClass().getName())//
+ .build();
+ }
+
+ }
+
+
+ @Before
+ public void compareDataSources() throws Exception {
+ // NOTE: the two DataSource instances ARE the same!
+ assertSame(dataSourceFromTxManager, dataSourceViaInjection);
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr9051/TransactionalAnnotatedConfigClassesWithoutAtConfigurationTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9051/TransactionalAnnotatedConfigClassesWithoutAtConfigurationTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..97dd76e26d7e6df3c888a9ecd177c2068a4365fc
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9051/TransactionalAnnotatedConfigClassesWithoutAtConfigurationTests.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2002-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr9051;
+
+import javax.sql.DataSource;
+
+import org.junit.Before;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.transaction.AfterTransaction;
+import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
+import org.springframework.tests.sample.beans.Employee;
+import org.springframework.transaction.PlatformTransactionManager;
+
+import static org.junit.Assert.*;
+
+/**
+ * Concrete implementation of {@link AbstractTransactionalAnnotatedConfigClassTests}
+ * that does not use a true {@link Configuration @Configuration class} but
+ * rather a lite mode configuration class (see the Javadoc for {@link Bean @Bean}
+ * for details).
+ *
+ * @author Sam Brannen
+ * @since 3.2
+ * @see Bean
+ * @see TransactionalAnnotatedConfigClassWithAtConfigurationTests
+ */
+@ContextConfiguration(classes = TransactionalAnnotatedConfigClassesWithoutAtConfigurationTests.AnnotatedFactoryBeans.class)
+public class TransactionalAnnotatedConfigClassesWithoutAtConfigurationTests extends
+ AbstractTransactionalAnnotatedConfigClassTests {
+
+ /**
+ * This is intentionally not annotated with {@code @Configuration}.
+ *
+ * Consequently, this class contains annotated factory bean methods
+ * instead of standard singleton bean methods.
+ */
+ // @Configuration
+ static class AnnotatedFactoryBeans {
+
+ @Bean
+ public Employee employee() {
+ Employee employee = new Employee();
+ employee.setName("John Smith");
+ employee.setAge(42);
+ employee.setCompany("Acme Widgets, Inc.");
+ return employee;
+ }
+
+ @Bean
+ public PlatformTransactionManager transactionManager() {
+ return new DataSourceTransactionManager(dataSource());
+ }
+
+ /**
+ * Since this method does not reside in a true {@code @Configuration class},
+ * it acts as a factory method when invoked directly (e.g., from
+ * {@link #transactionManager()}) and as a singleton bean when retrieved
+ * through the application context (e.g., when injected into the test
+ * instance). The result is that this method will be called twice:
+ *
+ * See in-line comments for details.
+ *
+ * @see AbstractTransactionalAnnotatedConfigClassTests#afterTransaction()
+ * @see AbstractTransactionalAnnotatedConfigClassTests#modifyTestDataWithinTransaction()
+ */
+ @AfterTransaction
+ @Override
+ public void afterTransaction() {
+ assertEquals("Deleting yoda", 1, deletePerson(YODA));
+
+ // NOTE: We would actually expect that there are now ZERO entries in the
+ // person table, since the transaction is rolled back by the framework;
+ // however, since our JdbcTemplate and the transaction manager used by
+ // the Spring TestContext Framework use two different DataSource
+ // instances, our insert statements were executed in transactions that
+ // are not controlled by the test framework. Consequently, there was no
+ // rollback for the two insert statements in
+ // modifyTestDataWithinTransaction().
+ //
+ assertNumRowsInPersonTable(2, "after a transactional test method");
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr9604/LookUpTxMgrViaTransactionManagementConfigurerTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9604/LookUpTxMgrViaTransactionManagementConfigurerTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..a7c76ce73242ef2b31cfb726261108f439600c73
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9604/LookUpTxMgrViaTransactionManagementConfigurerTests.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr9604;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.transaction.AfterTransaction;
+import org.springframework.test.context.transaction.BeforeTransaction;
+import org.springframework.tests.transaction.CallCountingTransactionManager;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.TransactionManagementConfigurer;
+import org.springframework.transaction.annotation.Transactional;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify the behavior requested in
+ * SPR-9604.
+ *
+ * @author Sam Brannen
+ * @since 3.2
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration
+@Transactional
+public class LookUpTxMgrViaTransactionManagementConfigurerTests {
+
+ private static final CallCountingTransactionManager txManager1 = new CallCountingTransactionManager();
+ private static final CallCountingTransactionManager txManager2 = new CallCountingTransactionManager();
+
+
+ @Configuration
+ static class Config implements TransactionManagementConfigurer {
+
+ @Override
+ public PlatformTransactionManager annotationDrivenTransactionManager() {
+ return txManager1();
+ }
+
+ @Bean
+ public PlatformTransactionManager txManager1() {
+ return txManager1;
+ }
+
+ @Bean
+ public PlatformTransactionManager txManager2() {
+ return txManager2;
+ }
+ }
+
+
+ @BeforeTransaction
+ public void beforeTransaction() {
+ txManager1.clear();
+ txManager2.clear();
+ }
+
+ @Test
+ public void transactionalTest() {
+ assertEquals(1, txManager1.begun);
+ assertEquals(1, txManager1.inflight);
+ assertEquals(0, txManager1.commits);
+ assertEquals(0, txManager1.rollbacks);
+
+ assertEquals(0, txManager2.begun);
+ assertEquals(0, txManager2.inflight);
+ assertEquals(0, txManager2.commits);
+ assertEquals(0, txManager2.rollbacks);
+ }
+
+ @AfterTransaction
+ public void afterTransaction() {
+ assertEquals(1, txManager1.begun);
+ assertEquals(0, txManager1.inflight);
+ assertEquals(0, txManager1.commits);
+ assertEquals(1, txManager1.rollbacks);
+
+ assertEquals(0, txManager2.begun);
+ assertEquals(0, txManager2.inflight);
+ assertEquals(0, txManager2.commits);
+ assertEquals(0, txManager2.rollbacks);
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpNonexistentTxMgrTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpNonexistentTxMgrTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..300fcd578e3e3a05b529a4e81c0e412c0d639be8
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpNonexistentTxMgrTests.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr9645;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.tests.transaction.CallCountingTransactionManager;
+import org.springframework.transaction.PlatformTransactionManager;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify the behavior requested in
+ * SPR-9645.
+ *
+ * @author Sam Brannen
+ * @since 3.2
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration
+public class LookUpNonexistentTxMgrTests {
+
+ private static final CallCountingTransactionManager txManager = new CallCountingTransactionManager();
+
+ @Configuration
+ static class Config {
+
+ @Bean
+ public PlatformTransactionManager transactionManager() {
+ return txManager;
+ }
+ }
+
+ @Test
+ public void nonTransactionalTest() {
+ assertEquals(0, txManager.begun);
+ assertEquals(0, txManager.inflight);
+ assertEquals(0, txManager.commits);
+ assertEquals(0, txManager.rollbacks);
+ }
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpTxMgrByTypeAndDefaultNameTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpTxMgrByTypeAndDefaultNameTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..74314c2ea6669aa90f8c57b8fb6d404fc211a991
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpTxMgrByTypeAndDefaultNameTests.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr9645;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.transaction.AfterTransaction;
+import org.springframework.test.context.transaction.BeforeTransaction;
+import org.springframework.tests.transaction.CallCountingTransactionManager;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.Transactional;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify the behavior requested in
+ * SPR-9645.
+ *
+ * @author Sam Brannen
+ * @since 3.2
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration
+@Transactional
+public class LookUpTxMgrByTypeAndDefaultNameTests {
+
+ private static final CallCountingTransactionManager txManager1 = new CallCountingTransactionManager();
+ private static final CallCountingTransactionManager txManager2 = new CallCountingTransactionManager();
+
+ @Configuration
+ static class Config {
+
+ @Bean
+ public PlatformTransactionManager transactionManager() {
+ return txManager1;
+ }
+
+ @Bean
+ public PlatformTransactionManager txManager2() {
+ return txManager2;
+ }
+ }
+
+ @BeforeTransaction
+ public void beforeTransaction() {
+ txManager1.clear();
+ txManager2.clear();
+ }
+
+ @Test
+ public void transactionalTest() {
+ assertEquals(1, txManager1.begun);
+ assertEquals(1, txManager1.inflight);
+ assertEquals(0, txManager1.commits);
+ assertEquals(0, txManager1.rollbacks);
+ }
+
+ @AfterTransaction
+ public void afterTransaction() {
+ assertEquals(1, txManager1.begun);
+ assertEquals(0, txManager1.inflight);
+ assertEquals(0, txManager1.commits);
+ assertEquals(1, txManager1.rollbacks);
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpTxMgrByTypeAndNameTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpTxMgrByTypeAndNameTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..d6ae560da6e4d75c558b0f0cd2ea3e4cfe2576a1
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpTxMgrByTypeAndNameTests.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2002-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr9645;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.transaction.AfterTransaction;
+import org.springframework.test.context.transaction.BeforeTransaction;
+import org.springframework.tests.transaction.CallCountingTransactionManager;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.Transactional;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify the behavior requested in
+ * SPR-9645.
+ *
+ * @author Sam Brannen
+ * @since 3.2
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration
+@Transactional("txManager1")
+public class LookUpTxMgrByTypeAndNameTests {
+
+ private static final CallCountingTransactionManager txManager1 = new CallCountingTransactionManager();
+ private static final CallCountingTransactionManager txManager2 = new CallCountingTransactionManager();
+
+ @Configuration
+ static class Config {
+
+ @Bean
+ public PlatformTransactionManager txManager1() {
+ return txManager1;
+ }
+
+ @Bean
+ public PlatformTransactionManager txManager2() {
+ return txManager2;
+ }
+ }
+
+ @BeforeTransaction
+ public void beforeTransaction() {
+ txManager1.clear();
+ txManager2.clear();
+ }
+
+ @Test
+ public void transactionalTest() {
+ assertEquals(1, txManager1.begun);
+ assertEquals(1, txManager1.inflight);
+ assertEquals(0, txManager1.commits);
+ assertEquals(0, txManager1.rollbacks);
+ }
+
+ @AfterTransaction
+ public void afterTransaction() {
+ assertEquals(1, txManager1.begun);
+ assertEquals(0, txManager1.inflight);
+ assertEquals(0, txManager1.commits);
+ assertEquals(1, txManager1.rollbacks);
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpTxMgrByTypeAndQualifierAtClassLevelTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpTxMgrByTypeAndQualifierAtClassLevelTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..455209b1760eb5adb9b1c5ebc6522b9d4c4cd793
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpTxMgrByTypeAndQualifierAtClassLevelTests.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr9645;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.transaction.AfterTransaction;
+import org.springframework.test.context.transaction.BeforeTransaction;
+import org.springframework.tests.transaction.CallCountingTransactionManager;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.Transactional;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify the behavior requested in
+ * SPR-9645.
+ *
+ * @author Sam Brannen
+ * @since 3.2
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration
+@Transactional("txManager1")
+public class LookUpTxMgrByTypeAndQualifierAtClassLevelTests {
+
+ private static final CallCountingTransactionManager txManager1 = new CallCountingTransactionManager();
+ private static final CallCountingTransactionManager txManager2 = new CallCountingTransactionManager();
+
+ @Configuration
+ static class Config {
+
+ @Bean
+ public PlatformTransactionManager txManager1() {
+ return txManager1;
+ }
+
+ @Bean
+ public PlatformTransactionManager txManager2() {
+ return txManager2;
+ }
+ }
+
+ @BeforeTransaction
+ public void beforeTransaction() {
+ txManager1.clear();
+ txManager2.clear();
+ }
+
+ @Test
+ public void transactionalTest() {
+ assertEquals(1, txManager1.begun);
+ assertEquals(1, txManager1.inflight);
+ assertEquals(0, txManager1.commits);
+ assertEquals(0, txManager1.rollbacks);
+ }
+
+ @AfterTransaction
+ public void afterTransaction() {
+ assertEquals(1, txManager1.begun);
+ assertEquals(0, txManager1.inflight);
+ assertEquals(0, txManager1.commits);
+ assertEquals(1, txManager1.rollbacks);
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpTxMgrByTypeAndQualifierAtMethodLevelTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpTxMgrByTypeAndQualifierAtMethodLevelTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..d9e20694f97f06e3b622d60a0ba11ab98a5d511b
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpTxMgrByTypeAndQualifierAtMethodLevelTests.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr9645;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.transaction.AfterTransaction;
+import org.springframework.test.context.transaction.BeforeTransaction;
+import org.springframework.tests.transaction.CallCountingTransactionManager;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.Transactional;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify the behavior requested in
+ * SPR-9645.
+ *
+ * @author Sam Brannen
+ * @since 3.2
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration
+public class LookUpTxMgrByTypeAndQualifierAtMethodLevelTests {
+
+ private static final CallCountingTransactionManager txManager1 = new CallCountingTransactionManager();
+ private static final CallCountingTransactionManager txManager2 = new CallCountingTransactionManager();
+
+ @Configuration
+ static class Config {
+
+ @Bean
+ public PlatformTransactionManager txManager1() {
+ return txManager1;
+ }
+
+ @Bean
+ public PlatformTransactionManager txManager2() {
+ return txManager2;
+ }
+ }
+
+ @BeforeTransaction
+ public void beforeTransaction() {
+ txManager1.clear();
+ txManager2.clear();
+ }
+
+ @Transactional("txManager1")
+ @Test
+ public void transactionalTest() {
+ assertEquals(1, txManager1.begun);
+ assertEquals(1, txManager1.inflight);
+ assertEquals(0, txManager1.commits);
+ assertEquals(0, txManager1.rollbacks);
+ }
+
+ @AfterTransaction
+ public void afterTransaction() {
+ assertEquals(1, txManager1.begun);
+ assertEquals(0, txManager1.inflight);
+ assertEquals(0, txManager1.commits);
+ assertEquals(1, txManager1.rollbacks);
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpTxMgrByTypeTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpTxMgrByTypeTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd748a127498fc82a18afcb5b5ec93a947ef5a18
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9645/LookUpTxMgrByTypeTests.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr9645;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.transaction.AfterTransaction;
+import org.springframework.test.context.transaction.BeforeTransaction;
+import org.springframework.tests.transaction.CallCountingTransactionManager;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.Transactional;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests that verify the behavior requested in
+ * SPR-9645.
+ *
+ * @author Sam Brannen
+ * @since 3.2
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration
+@Transactional
+public class LookUpTxMgrByTypeTests {
+
+ private static final CallCountingTransactionManager txManager = new CallCountingTransactionManager();
+
+ @Configuration
+ static class Config {
+
+ @Bean
+ public PlatformTransactionManager txManager() {
+ return txManager;
+ }
+ }
+
+ @BeforeTransaction
+ public void beforeTransaction() {
+ txManager.clear();
+ }
+
+ @Test
+ public void transactionalTest() {
+ assertEquals(1, txManager.begun);
+ assertEquals(1, txManager.inflight);
+ assertEquals(0, txManager.commits);
+ assertEquals(0, txManager.rollbacks);
+ }
+
+ @AfterTransaction
+ public void afterTransaction() {
+ assertEquals(1, txManager.begun);
+ assertEquals(0, txManager.inflight);
+ assertEquals(0, txManager.commits);
+ assertEquals(1, txManager.rollbacks);
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr9799/Spr9799AnnotationConfigTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9799/Spr9799AnnotationConfigTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..91c809c3dc8ba195beac7ba0c77feb87e134166f
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9799/Spr9799AnnotationConfigTests.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr9799;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+
+/**
+ * Integration tests used to assess claims raised in
+ * SPR-9799.
+ *
+ * @author Sam Brannen
+ * @since 3.2
+ * @see Spr9799XmlConfigTests
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration
+// NOTE: if we omit the @WebAppConfiguration declaration, the ApplicationContext will fail
+// to load since @EnableWebMvc requires that the context be a WebApplicationContext.
+@WebAppConfiguration
+public class Spr9799AnnotationConfigTests {
+
+ @Configuration
+ @EnableWebMvc
+ static class Config {
+ /* intentionally no beans defined */
+ }
+
+
+ @Test
+ public void applicationContextLoads() {
+ // no-op
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr9799/Spr9799XmlConfigTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9799/Spr9799XmlConfigTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..37c7f933847562e3b3cd8cc77d3ca8158d623ed5
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr9799/Spr9799XmlConfigTests.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr9799;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * Integration tests used to assess claims raised in
+ * SPR-9799.
+ *
+ * @author Sam Brannen
+ * @since 3.2
+ * @see Spr9799AnnotationConfigTests
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration
+public class Spr9799XmlConfigTests {
+
+ @Test
+ public void applicationContextLoads() {
+ // nothing to assert: we just want to make sure that the context loads without
+ // errors.
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/statements/SpringFailOnTimeoutTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/statements/SpringFailOnTimeoutTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd9d7bb452bca7af3eb81c3246bcc1701e8a5902
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/statements/SpringFailOnTimeoutTests.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2002-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.statements;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runners.model.Statement;
+import org.mockito.stubbing.Answer;
+
+import org.springframework.test.context.junit4.statements.SpringFailOnTimeout;
+
+import static org.mockito.Mockito.*;
+
+/**
+ * Unit tests for {@link SpringFailOnTimeout}.
+ *
+ * @author Igor Suhorukov
+ * @author Sam Brannen
+ * @since 4.3.17
+ */
+public class SpringFailOnTimeoutTests {
+
+ private Statement statement = mock(Statement.class);
+
+ @Rule
+ public final ExpectedException exception = ExpectedException.none();
+
+
+ @Test
+ public void nullNextStatement() throws Throwable {
+ exception.expect(IllegalArgumentException.class);
+ new SpringFailOnTimeout(null, 1);
+ }
+
+ @Test
+ public void negativeTimeout() throws Throwable {
+ exception.expect(IllegalArgumentException.class);
+ new SpringFailOnTimeout(statement, -1);
+ }
+
+ @Test
+ public void userExceptionPropagates() throws Throwable {
+ doThrow(new Boom()).when(statement).evaluate();
+
+ exception.expect(Boom.class);
+ new SpringFailOnTimeout(statement, 1).evaluate();
+ }
+
+ @Test
+ public void timeoutExceptionThrownIfNoUserException() throws Throwable {
+ doAnswer((Answer
+ *
+ *
+ * Expected Log Output
+ *
+ * INFO : org.springframework.test.context.junit4.spr4868.LifecycleBean - initializing
+ * INFO : org.springframework.test.context.junit4.spr4868.ExampleTest - beforeAllTests()
+ * INFO : org.springframework.test.context.junit4.spr4868.ExampleTest - setUp()
+ * INFO : org.springframework.test.context.junit4.spr4868.ExampleTest - test1()
+ * INFO : org.springframework.test.context.junit4.spr4868.ExampleTest - tearDown()
+ * INFO : org.springframework.test.context.junit4.spr4868.ExampleTest - beforeAllTests()
+ * INFO : org.springframework.test.context.junit4.spr4868.ExampleTest - setUp()
+ * INFO : org.springframework.test.context.junit4.spr4868.ExampleTest - test2()
+ * INFO : org.springframework.test.context.junit4.spr4868.ExampleTest - tearDown()
+ * INFO : org.springframework.test.context.junit4.spr4868.LifecycleBean - destroying
+ *
+ *
+ * @author Sam Brannen
+ * @since 3.2
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class })
+@ContextConfiguration
+public class Jsr250LifecycleTests {
+
+ private final Log logger = LogFactory.getLog(Jsr250LifecycleTests.class);
+
+
+ @Configuration
+ static class Config {
+
+ @Bean
+ public LifecycleBean lifecycleBean() {
+ return new LifecycleBean();
+ }
+ }
+
+
+ @Autowired
+ private LifecycleBean lifecycleBean;
+
+
+ @PostConstruct
+ public void beforeAllTests() {
+ logger.info("beforeAllTests()");
+ }
+
+ @PreDestroy
+ public void afterTestSuite() {
+ logger.info("afterTestSuite()");
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ logger.info("setUp()");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ logger.info("tearDown()");
+ }
+
+ @Test
+ public void test1() {
+ logger.info("test1()");
+ assertNotNull(lifecycleBean);
+ }
+
+ @Test
+ public void test2() {
+ logger.info("test2()");
+ assertNotNull(lifecycleBean);
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr4868/LifecycleBean.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr4868/LifecycleBean.java
new file mode 100644
index 0000000000000000000000000000000000000000..be527d05a90cedeef9bf514d964252209a6424da
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr4868/LifecycleBean.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2002-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr4868;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * @author Sam Brannen
+ * @since 3.2
+ */
+class LifecycleBean {
+
+ private final Log logger = LogFactory.getLog(LifecycleBean.class);
+
+
+ @PostConstruct
+ public void init() {
+ logger.info("initializing");
+ }
+
+ @PreDestroy
+ public void destroy() {
+ logger.info("destroying");
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr6128/AutowiredQualifierTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr6128/AutowiredQualifierTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..5c32bdfe37d08d3dbb798c76acd4b3ce99ca10f0
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr6128/AutowiredQualifierTests.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr6128;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.hamcrest.core.IsEqual.*;
+import static org.junit.Assert.*;
+
+/**
+ * Integration tests to verify claims made in SPR-6128.
+ *
+ * @author Sam Brannen
+ * @author Chris Beams
+ * @since 3.0
+ */
+@ContextConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+public class AutowiredQualifierTests {
+
+ @Autowired
+ private String foo;
+
+ @Autowired
+ @Qualifier("customFoo")
+ private String customFoo;
+
+
+ @Test
+ public void test() {
+ assertThat(foo, equalTo("normal"));
+ assertThat(customFoo, equalTo("custom"));
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/Spr8849Tests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/Spr8849Tests.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6429d9ff4ebbe8b7884fee7a65fd8b08d13bff3
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit4/spr8849/Spr8849Tests.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2002-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit4.spr8849;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * Test suite to investigate claims raised in
+ * SPR-8849.
+ *
+ * Work Around
+ * Solution
+ *
+ * When a {@code @ContextConfiguration} test class references a config class
+ * missing an {@code @Configuration} annotation, {@code @Bean} dependencies are
+ * wired successfully but the bean lifecycle is not applied (no init methods are
+ * invoked, for example). Adding the missing {@code @Configuration} annotation
+ * solves the problem, however the problem and solution isn't obvious since
+ * wiring/injection appeared to work.
+ *
+ *
+ * @author Sam Brannen
+ * @author Phillip Webb
+ * @since 3.2
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = AnnotatedConfigClassesWithoutAtConfigurationTests.AnnotatedFactoryBeans.class)
+public class AnnotatedConfigClassesWithoutAtConfigurationTests {
+
+ /**
+ * This is intentionally not annotated with {@code @Configuration}.
+ * Consequently, this class contains what we call annotated factory bean
+ * methods instead of standard bean definition methods.
+ */
+ static class AnnotatedFactoryBeans {
+
+ static final AtomicInteger enigmaCallCount = new AtomicInteger();
+
+
+ @Bean
+ public String enigma() {
+ return "enigma #" + enigmaCallCount.incrementAndGet();
+ }
+
+ @Bean
+ public LifecycleBean lifecycleBean() {
+ // The following call to enigma() literally invokes the local
+ // enigma() method, not a CGLIB proxied version, since these methods
+ // are essentially factory bean methods.
+ LifecycleBean bean = new LifecycleBean(enigma());
+ assertFalse(bean.isInitialized());
+ return bean;
+ }
+ }
+
+
+ @Autowired
+ private String enigma;
+
+ @Autowired
+ private LifecycleBean lifecycleBean;
+
+
+ @Test
+ public void testSPR_9051() throws Exception {
+ assertNotNull(enigma);
+ assertNotNull(lifecycleBean);
+ assertTrue(lifecycleBean.isInitialized());
+ Set
+ *
+ *
+ * Consequently, the {@link JdbcTemplate} used by this test instance and
+ * the {@link PlatformTransactionManager} used by the Spring TestContext
+ * Framework will operate on two different {@code DataSource} instances,
+ * which is almost certainly not the desired or intended behavior.
+ */
+ @Bean
+ public DataSource dataSource() {
+ return new EmbeddedDatabaseBuilder()//
+ .addScript("classpath:/org/springframework/test/jdbc/schema.sql")//
+ // Ensure that this in-memory database is only used by this class:
+ .setName(getClass().getName())//
+ .build();
+ }
+
+ }
+
+
+ @Before
+ public void compareDataSources() throws Exception {
+ // NOTE: the two DataSource instances are NOT the same!
+ assertNotSame(dataSourceFromTxManager, dataSourceViaInjection);
+ }
+
+ /**
+ * Overrides {@code afterTransaction()} in order to assert a different result.
+ *
+ * > hierarchyAttributes = resolveContextHierarchyAttributes(BareAnnotations.class);
+ assertEquals(1, hierarchyAttributes.size());
+ List
> hierarchyAttributes = resolveContextHierarchyAttributes(SingleTestClassWithSingleLevelContextHierarchy.class);
+ assertEquals(1, hierarchyAttributes.size());
+ List
> hierarchyAttributes = resolveContextHierarchyAttributes(testClass);
+ assertEquals(1, hierarchyAttributes.size());
+
+ List
> hierarchyAttributes = resolveContextHierarchyAttributes(testClass);
+ assertEquals(1, hierarchyAttributes.size());
+
+ List
> hierarchyAttributes = resolveContextHierarchyAttributes(TestClass3WithSingleLevelContextHierarchy.class);
+ assertEquals(3, hierarchyAttributes.size());
+
+ List
> hierarchyAttributes = resolveContextHierarchyAttributes(TestClass3WithSingleLevelContextHierarchyFromMetaAnnotation.class);
+ assertEquals(3, hierarchyAttributes.size());
+
+ List
> hierarchyAttributes) {
+ assertEquals(2, hierarchyAttributes.size());
+
+ List
> hierarchyAttributes = resolveContextHierarchyAttributes(TestClass3WithMultiLevelContextHierarchy.class);
+ assertEquals(3, hierarchyAttributes.size());
+
+ List