diff --git a/spring-test/src/main/java/org/springframework/test/context/ContextCustomizer.java b/spring-test/src/main/java/org/springframework/test/context/ContextCustomizer.java index 05e2c09dd0..d9462faadb 100644 --- a/spring-test/src/main/java/org/springframework/test/context/ContextCustomizer.java +++ b/spring-test/src/main/java/org/springframework/test/context/ContextCustomizer.java @@ -16,34 +16,34 @@ package org.springframework.test.context; -import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; /** - * Strategy interface for customizing {@link ApplicationContext application contexts} that - * are created and managed by the Spring TestContext Framework. + * Strategy interface for customizing {@link ConfigurableApplicationContext + * application contexts} that are created and managed by the Spring + * TestContext Framework. * - *

Customizers are loaded via {@link ContextCustomizerFactory} classes registered in - * {@code spring.factories}. + *

Customizers are created by {@link ContextCustomizerFactory} implementations. * - *

Implementations should take care to implement correct {@code equals} and - * {@code hashCode} methods since customizers form part of the - * {@link MergedContextConfiguration} which is used as a cache key. + *

Implementations must implement correct {@code equals} and {@code hashCode} + * methods since customizers form part of the {@link MergedContextConfiguration} + * which is used as a cache key. * * @author Phillip Webb + * @author Sam Brannen * @since 4.3 * @see ContextCustomizerFactory - * @see org.springframework.test.context.support.AbstractContextLoader + * @see org.springframework.test.context.support.AbstractContextLoader#customizeContext */ public interface ContextCustomizer { /** - * Called before bean definitions are read to customize the - * {@link ConfigurableApplicationContext}. - * @param context the context that should be prepared - * @param mergedContextConfiguration the merged context configuration + * Customize the supplied {@code ConfigurableApplicationContext} after + * bean definitions have been loaded into the context but before the + * context has been refreshed. + * @param context the context to customize + * @param mergedConfig the merged context configuration */ - void customizeContext(ConfigurableApplicationContext context, - MergedContextConfiguration mergedContextConfiguration); + void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig); } diff --git a/spring-test/src/main/java/org/springframework/test/context/ContextCustomizerFactory.java b/spring-test/src/main/java/org/springframework/test/context/ContextCustomizerFactory.java index f9c77277b3..9f07700a38 100644 --- a/spring-test/src/main/java/org/springframework/test/context/ContextCustomizerFactory.java +++ b/spring-test/src/main/java/org/springframework/test/context/ContextCustomizerFactory.java @@ -18,29 +18,35 @@ package org.springframework.test.context; import java.util.List; -import org.springframework.context.ConfigurableApplicationContext; - /** - * Factory registered in {@code spring.factories} that is used to create - * {@link ContextCustomizer ContextCustomizers}. Factories are called after - * {@link ContextLoader ContextLoaders} have been triggered but before the + * Factory for creating {@link ContextCustomizer ContextCustomizers}. + * + *

Factories are invoked after {@link ContextLoader ContextLoaders} have + * processed context configuration attributes but before the * {@link MergedContextConfiguration} is created. * + *

By default, the Spring TestContext Framework will use the + * {@link org.springframework.core.io.support.SpringFactoriesLoader SpringFactoriesLoader} + * mechanism for loading factories configured in all {@code META-INF/spring.factories} + * files on the classpath. + * * @author Phillip Webb + * @author Sam Brannen * @since 4.3 */ public interface ContextCustomizerFactory { /** - * Get the {@link ContextCustomizer} (if any) that should be used to customize the - * {@link ConfigurableApplicationContext} when it is created. + * Create a {@link ContextCustomizer} that should be used to customize a + * {@link org.springframework.context.ConfigurableApplicationContext ConfigurableApplicationContext} + * before it is refreshed. * @param testClass the test class - * @param configurationAttributes he list of context configuration attributes for the - * test class, ordered bottom-up (i.e., as if we were traversing up the class - * hierarchy); never {@code null} or empty. - * @return a {@link ContextCustomizer} or {@code null} + * @param configAttributes the list of context configuration attributes for + * the test class, ordered bottom-up (i.e., as if we were traversing + * up the class hierarchy); never {@code null} or empty + * @return a {@link ContextCustomizer} or {@code null} if no customizer should + * be used */ - ContextCustomizer getContextCustomizer(Class testClass, - List configurationAttributes); + ContextCustomizer createContextCustomizer(Class testClass, List configAttributes); } diff --git a/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java b/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java index 1476f5863b..dc98c1c276 100644 --- a/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java +++ b/spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java @@ -55,6 +55,7 @@ import org.springframework.util.StringUtils; * that was loaded using properties of this {@code MergedContextConfiguration}. * * @author Sam Brannen + * @author Phillip Webb * @since 3.1 * @see ContextConfiguration * @see ContextHierarchy @@ -74,6 +75,8 @@ public class MergedContextConfiguration implements Serializable { private static final Set>> EMPTY_INITIALIZER_CLASSES = Collections.>> emptySet(); + private static final Set EMPTY_CONTEXT_CUSTOMIZERS = Collections. emptySet(); + private final Class testClass; @@ -113,6 +116,11 @@ public class MergedContextConfiguration implements Serializable { Collections.unmodifiableSet(contextInitializerClasses) : EMPTY_INITIALIZER_CLASSES); } + private static Set processContextCustomizers(Set contextCustomizers) { + return (contextCustomizers != null ? + Collections.unmodifiableSet(contextCustomizers) : EMPTY_CONTEXT_CUSTOMIZERS); + } + private static String[] processActiveProfiles(String[] activeProfiles) { if (activeProfiles == null) { return EMPTY_STRING_ARRAY; @@ -247,8 +255,8 @@ public class MergedContextConfiguration implements Serializable { *

If a {@code null} value is supplied for {@code locations}, * {@code classes}, {@code activeProfiles}, {@code propertySourceLocations}, * or {@code propertySourceProperties} an empty array will be stored instead. - * If a {@code null} value is supplied for the - * {@code contextInitializerClasses} an empty set will be stored instead. + * If a {@code null} value is supplied for {@code contextInitializerClasses} + * or {@code contextCustomizers}, an empty set will be stored instead. * Furthermore, active profiles will be sorted, and duplicate profiles * will be removed. * @param testClass the test class for which the configuration was merged @@ -258,11 +266,12 @@ public class MergedContextConfiguration implements Serializable { * @param activeProfiles the merged active bean definition profiles * @param propertySourceLocations the merged {@code PropertySource} locations * @param propertySourceProperties the merged {@code PropertySource} properties + * @param contextCustomizers the context customizers * @param contextLoader the resolved {@code ContextLoader} * @param cacheAwareContextLoaderDelegate a cache-aware context loader * delegate with which to retrieve the parent context * @param parent the parent configuration or {@code null} if there is no parent - * @since 4.2 + * @since 4.3 */ public MergedContextConfiguration(Class testClass, String[] locations, Class[] classes, Set>> contextInitializerClasses, @@ -277,7 +286,7 @@ public class MergedContextConfiguration implements Serializable { this.activeProfiles = processActiveProfiles(activeProfiles); this.propertySourceLocations = processStrings(propertySourceLocations); this.propertySourceProperties = processStrings(propertySourceProperties); - this.contextCustomizers = Collections.unmodifiableSet(contextCustomizers); + this.contextCustomizers = processContextCustomizers(contextCustomizers); this.contextLoader = contextLoader; this.cacheAwareContextLoaderDelegate = cacheAwareContextLoaderDelegate; this.parent = parent; @@ -390,7 +399,7 @@ public class MergedContextConfiguration implements Serializable { * when the application context is loaded. */ public Set getContextCustomizers() { - return contextCustomizers; + return this.contextCustomizers; } /** @@ -515,6 +524,7 @@ public class MergedContextConfiguration implements Serializable { * {@linkplain #getActiveProfiles() active profiles}, * {@linkplain #getPropertySourceLocations() property source locations}, * {@linkplain #getPropertySourceProperties() property source properties}, + * {@linkplain #getContextCustomizers() context customizers}, * the name of the {@link #getContextLoader() ContextLoader}, and the * {@linkplain #getParent() parent configuration}. */ @@ -528,6 +538,7 @@ public class MergedContextConfiguration implements Serializable { .append("activeProfiles", ObjectUtils.nullSafeToString(this.activeProfiles)) .append("propertySourceLocations", ObjectUtils.nullSafeToString(this.propertySourceLocations)) .append("propertySourceProperties", ObjectUtils.nullSafeToString(this.propertySourceProperties)) + .append("contextCustomizers", this.contextCustomizers) .append("contextLoader", nullSafeToString(this.contextLoader)) .append("parent", this.parent) .toString(); diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AbstractContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/support/AbstractContextLoader.java index 279bccf2d6..f17782f8a6 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/AbstractContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/AbstractContextLoader.java @@ -28,7 +28,6 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextException; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.GenericTypeResolver; import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.core.env.PropertySource; @@ -58,10 +57,13 @@ import org.springframework.util.ResourceUtils; * * @author Sam Brannen * @author Juergen Hoeller + * @author Phillip Webb * @since 2.5 * @see #generateDefaultLocations * @see #getResourceSuffixes * @see #modifyLocations + * @see #prepareContext + * @see #customizeContext */ public abstract class AbstractContextLoader implements SmartContextLoader { @@ -109,8 +111,6 @@ public abstract class AbstractContextLoader implements SmartContextLoader { * {@linkplain MergedContextConfiguration#getPropertySourceProperties() * inlined properties} from the supplied {@code MergedContextConfiguration} * to the {@code Environment} of the context. - *

  • Calls any {@link MergedContextConfiguration#getContextCustomizers() - * ContextCustomizers} that are part of the {@link MergedContextConfiguration}.
  • *
  • Determines what (if any) context initializer classes have been supplied * via the {@code MergedContextConfiguration} and instantiates and * {@linkplain ApplicationContextInitializer#initialize invokes} each with the @@ -173,18 +173,16 @@ public abstract class AbstractContextLoader implements SmartContextLoader { /** * Customize the {@link ConfigurableApplicationContext} created by this - * {@code ContextLoader} after bean definitions have been - * loaded into the context but before the context is refreshed. - * - *

    The default implementation triggers all the - * {@link MergedContextConfiguration#getContextCustomizers() context customizers} that - * have been registered with the {@code mergedConfig}. - * + * {@code ContextLoader} after bean definitions have been loaded + * into the context but before the context has been refreshed. + *

    The default implementation delegates to all + * {@link MergedContextConfiguration#getContextCustomizers context customizers} + * that have been registered with the supplied {@code mergedConfig}. * @param context the newly created application context * @param mergedConfig the merged context configuration * @since 4.3 */ - protected void customizeContext(GenericApplicationContext context, MergedContextConfiguration mergedConfig) { + protected void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) { for (ContextCustomizer contextCustomizer : mergedConfig.getContextCustomizers()) { contextCustomizer.customizeContext(context, mergedConfig); } diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AbstractDelegatingSmartContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/support/AbstractDelegatingSmartContextLoader.java index 4fb04597cb..c0ae608ed7 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/AbstractDelegatingSmartContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/AbstractDelegatingSmartContextLoader.java @@ -253,7 +253,8 @@ public abstract class AbstractDelegatingSmartContextLoader implements SmartConte } // If neither of the candidates supports the mergedConfig based on resources but - // ACIs were declared, then delegate to the annotation config loader. + // ACIs or customizers were declared, then delegate to the annotation config + // loader. if (!mergedConfig.getContextInitializerClasses().isEmpty() || !mergedConfig.getContextCustomizers().isEmpty()) { return delegateLoading(getAnnotationConfigLoader(), mergedConfig); } diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AbstractGenericContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/support/AbstractGenericContextLoader.java index 3b924f0879..4bc65d2941 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/AbstractGenericContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/AbstractGenericContextLoader.java @@ -16,7 +16,6 @@ package org.springframework.test.context.support; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -53,6 +52,7 @@ import org.springframework.util.StringUtils; * * @author Sam Brannen * @author Juergen Hoeller + * @author Phillip Webb * @since 2.5 * @see #loadContext(MergedContextConfiguration) * @see #loadContext(String...) @@ -92,6 +92,8 @@ public abstract class AbstractGenericContextLoader extends AbstractContextLoader * annotation configuration processors.

  • *
  • Calls {@link #customizeContext(GenericApplicationContext)} to allow for customizing the context * before it is refreshed.
  • + *
  • Calls {@link #customizeContext(ConfigurableApplicationContext, MergedContextConfiguration)} to + * allow for customizing the context before it is refreshed.
  • *
  • {@link ConfigurableApplicationContext#refresh Refreshes} the * context and registers a JVM shutdown hook for it.
  • * @@ -206,6 +208,7 @@ public abstract class AbstractGenericContextLoader extends AbstractContextLoader * @see GenericApplicationContext#setAllowBeanDefinitionOverriding * @see GenericApplicationContext#setResourceLoader * @see GenericApplicationContext#setId + * @see #prepareContext(ConfigurableApplicationContext, MergedContextConfiguration) * @since 2.5 */ protected void prepareContext(GenericApplicationContext context) { @@ -279,6 +282,7 @@ public abstract class AbstractGenericContextLoader extends AbstractContextLoader * @param context the newly created application context * @see #loadContext(MergedContextConfiguration) * @see #loadContext(String...) + * @see #customizeContext(ConfigurableApplicationContext, MergedContextConfiguration) * @since 2.5 */ protected void customizeContext(GenericApplicationContext context) { diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java b/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java index 77e375cb72..51bbee68da 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java @@ -410,12 +410,16 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot return processMergedContextConfiguration(mergedConfig); } + /** + * @since 4.3 + */ private Set getContextCustomizers(Class testClass, - List configurationAttributes) { - List factories = geContextCustomizerFactories(); + List configAttributes) { + + List factories = getContextCustomizerFactories(); Set customizers = new LinkedHashSet(factories.size()); for (ContextCustomizerFactory factory : factories) { - ContextCustomizer customizer = factory.getContextCustomizer(testClass, configurationAttributes); + ContextCustomizer customizer = factory.createContextCustomizer(testClass, configAttributes); if (customizer != null) { customizers.add(customizer); } @@ -424,13 +428,20 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot } /** - * Get the default {@link ContextCustomizerFactory} instances for this bootstrapper. + * Get the {@link ContextCustomizerFactory} instances for this bootstrapper. + *

    The default implementation uses the {@link SpringFactoriesLoader} mechanism + * for loading factories configured in all {@code META-INF/spring.factories} + * files on the classpath. + * @since 4.3 + * @see SpringFactoriesLoader#loadFactories */ - protected List geContextCustomizerFactories() { - return SpringFactoriesLoader.loadFactories(ContextCustomizerFactory.class, - getClass().getClassLoader()); + protected List getContextCustomizerFactories() { + return SpringFactoriesLoader.loadFactories(ContextCustomizerFactory.class, getClass().getClassLoader()); } + /** + * @since 4.3 + */ private boolean areAllEmpty(Collection... collections) { for (Collection collection : collections) { if (!collection.isEmpty()) { diff --git a/spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.java b/spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.java index 53a3b7250f..a74ca6a2ca 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/AbstractGenericWebContextLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * 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. @@ -53,6 +53,7 @@ import org.springframework.web.context.support.GenericWebApplicationContext; * {@link #loadBeanDefinitions}. * * @author Sam Brannen + * @author Phillip Webb * @since 3.2 * @see #loadContext(MergedContextConfiguration) * @see #loadContext(String...) @@ -256,10 +257,14 @@ public abstract class AbstractGenericWebContextLoader extends AbstractContextLoa * loader after bean definitions have been loaded into the context but * before the context is refreshed. * + *

    The default implementation simply delegates to + * {@link AbstractContextLoader#customizeContext(ConfigurableApplicationContext, MergedContextConfiguration)}. + * * @param context the newly created web application context * @param webMergedConfig the merged context configuration to use to load the * web application context * @see #loadContext(MergedContextConfiguration) + * @see #customizeContext(ConfigurableApplicationContext, MergedContextConfiguration) */ protected void customizeContext(GenericWebApplicationContext context, WebMergedContextConfiguration webMergedConfig) { super.customizeContext(context, webMergedConfig); diff --git a/spring-test/src/main/java/org/springframework/test/context/web/WebMergedContextConfiguration.java b/spring-test/src/main/java/org/springframework/test/context/web/WebMergedContextConfiguration.java index cd1187b535..98bbdad2a9 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/WebMergedContextConfiguration.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/WebMergedContextConfiguration.java @@ -22,6 +22,7 @@ import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.style.ToStringCreator; import org.springframework.test.context.CacheAwareContextLoaderDelegate; +import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.ContextLoader; import org.springframework.test.context.MergedContextConfiguration; import org.springframework.util.ObjectUtils; @@ -132,12 +133,47 @@ public class WebMergedContextConfiguration extends MergedContextConfiguration { String resourceBasePath, ContextLoader contextLoader, CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, MergedContextConfiguration parent) { - super(testClass, locations, classes, contextInitializerClasses, activeProfiles, propertySourceLocations, - propertySourceProperties, contextLoader, cacheAwareContextLoaderDelegate, parent); - - this.resourceBasePath = !StringUtils.hasText(resourceBasePath) ? "" : resourceBasePath; + this(testClass, locations, classes, contextInitializerClasses, activeProfiles, propertySourceLocations, + propertySourceProperties, null, resourceBasePath, contextLoader, cacheAwareContextLoaderDelegate, parent); } + /** + * Create a new {@code WebMergedContextConfiguration} instance for the + * supplied parameters. + *

    If a {@code null} value is supplied for {@code locations}, + * {@code classes}, {@code activeProfiles}, {@code propertySourceLocations}, + * or {@code propertySourceProperties} an empty array will be stored instead. + * If a {@code null} value is supplied for {@code contextInitializerClasses} + * or {@code contextCustomizers}, an empty set will be stored instead. + * If an empty value is supplied for the {@code resourceBasePath} + * an empty string will be used. Furthermore, active profiles will be sorted, + * and duplicate profiles will be removed. + * @param testClass the test class for which the configuration was merged + * @param locations the merged context resource locations + * @param classes the merged annotated classes + * @param contextInitializerClasses the merged context initializer classes + * @param activeProfiles the merged active bean definition profiles + * @param propertySourceLocations the merged {@code PropertySource} locations + * @param propertySourceProperties the merged {@code PropertySource} properties + * @param contextCustomizers the context customizers + * @param resourceBasePath the resource path to the root directory of the web application + * @param contextLoader the resolved {@code ContextLoader} + * @param cacheAwareContextLoaderDelegate a cache-aware context loader + * delegate with which to retrieve the parent context + * @param parent the parent configuration or {@code null} if there is no parent + * @since 4.3 + */ + public WebMergedContextConfiguration(Class testClass, String[] locations, Class[] classes, + Set>> contextInitializerClasses, + String[] activeProfiles, String[] propertySourceLocations, String[] propertySourceProperties, + Set contextCustomizers, String resourceBasePath, ContextLoader contextLoader, + CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, MergedContextConfiguration parent) { + + super(testClass, locations, classes, contextInitializerClasses, activeProfiles, propertySourceLocations, + propertySourceProperties, contextCustomizers, contextLoader, cacheAwareContextLoaderDelegate, parent); + + this.resourceBasePath = (StringUtils.hasText(resourceBasePath) ? resourceBasePath : ""); + } /** * Get the resource path to the root directory of the web application for the @@ -182,6 +218,7 @@ public class WebMergedContextConfiguration extends MergedContextConfiguration { * {@linkplain #getActiveProfiles() active profiles}, * {@linkplain #getPropertySourceLocations() property source locations}, * {@linkplain #getPropertySourceProperties() property source properties}, + * {@linkplain #getContextCustomizers() context customizers}, * {@linkplain #getResourceBasePath() resource base path}, the name of the * {@link #getContextLoader() ContextLoader}, and the * {@linkplain #getParent() parent configuration}. @@ -196,6 +233,7 @@ public class WebMergedContextConfiguration extends MergedContextConfiguration { .append("activeProfiles", ObjectUtils.nullSafeToString(getActiveProfiles())) .append("propertySourceLocations", ObjectUtils.nullSafeToString(getPropertySourceLocations())) .append("propertySourceProperties", ObjectUtils.nullSafeToString(getPropertySourceProperties())) + .append("contextCustomizers", getContextCustomizers()) .append("resourceBasePath", getResourceBasePath()) .append("contextLoader", nullSafeToString(getContextLoader())) .append("parent", getParent()) diff --git a/spring-test/src/test/java/org/springframework/test/context/MergedContextConfigurationTests.java b/spring-test/src/test/java/org/springframework/test/context/MergedContextConfigurationTests.java index 733f7c0c3b..0409e11f69 100644 --- a/spring-test/src/test/java/org/springframework/test/context/MergedContextConfigurationTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/MergedContextConfigurationTests.java @@ -39,6 +39,7 @@ import static org.mockito.Mockito.*; * {@link org.springframework.test.context.cache.ContextCache ContextCache}. * * @author Sam Brannen + * @author Phillip Webb * @since 3.1 */ public class MergedContextConfigurationTests { @@ -402,32 +403,31 @@ public class MergedContextConfigurationTests { assertNotEquals(mergedConfig2, mergedConfig1); } + /** + * @since 4.3 + */ @Test public void equalsWithSameContextCustomizers() { - Set customizers1 = Collections.singleton( - mock(ContextCustomizer.class)); - MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration( - getClass(), EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, null, - EMPTY_STRING_ARRAY, null, null, customizers1, loader, null, null); - MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration( - getClass(), EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, null, - EMPTY_STRING_ARRAY, null, null, customizers1, loader, null, null); + Set customizers = Collections.singleton(mock(ContextCustomizer.class)); + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, null, EMPTY_STRING_ARRAY, null, null, customizers, loader, null, null); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, null, EMPTY_STRING_ARRAY, null, null, customizers, loader, null, null); assertEquals(mergedConfig1, mergedConfig2); } + /** + * @since 4.3 + */ @Test public void equalsWithDifferentContextCustomizers() { - Set customizers1 = Collections.singleton( - mock(ContextCustomizer.class)); - Set customizers2 = Collections.singleton( - mock(ContextCustomizer.class)); + Set customizers1 = Collections.singleton(mock(ContextCustomizer.class)); + Set customizers2 = Collections.singleton(mock(ContextCustomizer.class)); - MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration( - getClass(), EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, null, - EMPTY_STRING_ARRAY, null, null, customizers1, loader, null, null); - MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration( - getClass(), EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, null, - EMPTY_STRING_ARRAY, null, null, customizers2, loader, null, null); + MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, null, EMPTY_STRING_ARRAY, null, null, customizers1, loader, null, null); + MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, + EMPTY_CLASS_ARRAY, null, EMPTY_STRING_ARRAY, null, null, customizers2, loader, null, null); assertNotEquals(mergedConfig1, mergedConfig2); assertNotEquals(mergedConfig2, mergedConfig1); } diff --git a/spring-test/src/test/java/org/springframework/test/context/TestContextManagerVerifyAttributesTests.java b/spring-test/src/test/java/org/springframework/test/context/TestContextManagerVerifyAttributesTests.java deleted file mode 100644 index 72d83a38c6..0000000000 --- a/spring-test/src/test/java/org/springframework/test/context/TestContextManagerVerifyAttributesTests.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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 - * - * http://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; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ConfigurableApplicationContext; - -import static org.hamcrest.CoreMatchers.*; - -/** - * JUnit 4 based unit test for {@link TestContextManager}, which verifies - * ContextConfiguration attributes are defined. - * - * @author Phillip Webb - * @since 4.3 - */ -public class TestContextManagerVerifyAttributesTests { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void processContextConfigurationWithMissingContextConfigAttributes() { - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage(containsString("was unable to detect defaults, " - + "and no ApplicationContextInitializers or ContextCustomizers were " - + "declared for context configuration")); - new TestContextManager(MissingContextAttributes.class); - } - - @Test - public void processContextConfigurationWitListener() { - new TestContextManager(WithInitializer.class); - } - - - @ContextConfiguration - private static class MissingContextAttributes { - - } - - @ContextConfiguration(initializers=ExampleInitializer.class) - private static class WithInitializer { - - } - - static class ExampleInitializer implements ApplicationContextInitializer { - - @Override - public void initialize(ConfigurableApplicationContext applicationContext) { - } - - } -} diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/ContextCustomizerSpringRunnerTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/ContextCustomizerSpringRunnerTests.java index c978c4977d..13acb3cd2c 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/ContextCustomizerSpringRunnerTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/ContextCustomizerSpringRunnerTests.java @@ -16,73 +16,50 @@ package org.springframework.test.context.junit4; -import java.util.Collections; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ConfigurableApplicationContext; import org.springframework.test.context.BootstrapWith; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.ContextConfigurationAttributes; import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.ContextCustomizerFactory; -import org.springframework.test.context.MergedContextConfiguration; import org.springframework.test.context.junit4.ContextCustomizerSpringRunnerTests.CustomTestContextBootstrapper; import org.springframework.test.context.support.DefaultTestContextBootstrapper; +import static java.util.Collections.*; import static org.junit.Assert.*; /** * JUnit 4 based integration test which verifies support of * {@link ContextCustomizerFactory} and {@link ContextCustomizer}. * + * @author Sam Brannen * @author Phillip Webb * @since 4.3 */ -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(SpringRunner.class) @BootstrapWith(CustomTestContextBootstrapper.class) -@ContextConfiguration public class ContextCustomizerSpringRunnerTests { - @Autowired - private MyBean myBean; + @Autowired String foo; + @Test - public void injectedMyBean() throws Exception { - assertNotNull(this.myBean); + public void injectedBean() { + assertEquals("foo", foo); } - public static class CustomTestContextBootstrapper - extends DefaultTestContextBootstrapper { + + static class CustomTestContextBootstrapper extends DefaultTestContextBootstrapper { @Override - protected List geContextCustomizerFactories() { - return Collections.singletonList(new ContextCustomizerFactory() { - - @Override - public ContextCustomizer getContextCustomizer(Class testClass, - List configurationAttributes) { - return new TestContextCustomizers(); - } - - }); + protected List getContextCustomizerFactories() { + return singletonList((testClass, configAttributes) -> + // ContextCustomizer as lambda expression: + (context, mergedConfig) -> context.getBeanFactory().registerSingleton("foo", "foo")); } - - } - - public static class TestContextCustomizers implements ContextCustomizer { - - @Override - public void customizeContext(ConfigurableApplicationContext context, - MergedContextConfiguration mergedContextConfiguration) { - context.getBeanFactory().registerSingleton("mybean", new MyBean()); - } - - } - - public static class MyBean { } } diff --git a/spring-test/src/test/java/org/springframework/test/context/support/BootstrapTestUtilsMergedConfigTests.java b/spring-test/src/test/java/org/springframework/test/context/support/BootstrapTestUtilsMergedConfigTests.java index 1b509fc92e..b499c257a8 100644 --- a/spring-test/src/test/java/org/springframework/test/context/support/BootstrapTestUtilsMergedConfigTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/support/BootstrapTestUtilsMergedConfigTests.java @@ -63,7 +63,7 @@ public class BootstrapTestUtilsMergedConfigTests extends AbstractContextConfigur public void buildMergedConfigWithContextConfigurationWithoutLocationsClassesOrInitializers() { exception.expect(IllegalStateException.class); exception.expectMessage(startsWith("DelegatingSmartContextLoader was unable to detect defaults, " - + "and no ApplicationContextInitializers or ContextCustomizers were declared for context configuration attribute")); + + "and no ApplicationContextInitializers or ContextCustomizers were declared for context configuration attributes")); buildMergedContextConfiguration(MissingContextAttributesTestCase.class); }