Allow @ContextConfiguration to be omitted
Prior to this commit, the @ContextConfiguration annotation was required to be present even if default XML files, Groovy scripts, or @Configuration classes were detected; however, in such cases the @ContextConfiguration was typically declared empty and therefore seemingly unnecessary boilerplate. This commit permits @ContextConfiguration to be omitted whenever it can be reasonably deduced. Consequently, integration tests such as the following are now supported. @RunWith(SpringRunner.class) public class MyTest { @Autowired String myBean; @Test public void example() { /* ... */ } @Configuration static class Config { @Bean String myBean() { return "Hello"; } } } Issue: SPR-13955
This commit is contained in:
parent
0a56667093
commit
2244461778
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
|
@ -34,6 +34,7 @@ import org.springframework.util.StringUtils;
|
|||
* attributes declared via {@link ContextConfiguration @ContextConfiguration}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @author Phillip Webb
|
||||
* @since 3.1
|
||||
* @see ContextConfiguration
|
||||
* @see SmartContextLoader#processContextConfiguration(ContextConfigurationAttributes)
|
||||
|
@ -43,6 +44,10 @@ public class ContextConfigurationAttributes {
|
|||
|
||||
private static final Log logger = LogFactory.getLog(ContextConfigurationAttributes.class);
|
||||
|
||||
private static final String[] EMPTY_LOCATIONS = new String[0];
|
||||
|
||||
private static final Class<?>[] EMPTY_CLASSES = new Class<?>[0];
|
||||
|
||||
private final Class<?> declaringClass;
|
||||
|
||||
private Class<?>[] classes;
|
||||
|
@ -60,6 +65,18 @@ public class ContextConfigurationAttributes {
|
|||
private final Class<? extends ContextLoader> contextLoaderClass;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new {@link ContextConfigurationAttributes} instance with default
|
||||
* values.
|
||||
* @param declaringClass the test class that declared {@code @ContextConfiguration},
|
||||
* either explicitly or implicitly
|
||||
* @since 4.3
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public ContextConfigurationAttributes(Class<?> declaringClass) {
|
||||
this(declaringClass, EMPTY_LOCATIONS, EMPTY_CLASSES, false, (Class[]) EMPTY_CLASSES, true, ContextLoader.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@link ContextConfigurationAttributes} instance for the
|
||||
* supplied {@link ContextConfiguration @ContextConfiguration} annotation and
|
||||
|
@ -158,7 +175,8 @@ public class ContextConfigurationAttributes {
|
|||
|
||||
/**
|
||||
* Get the {@linkplain Class class} that declared the
|
||||
* {@link ContextConfiguration @ContextConfiguration} annotation.
|
||||
* {@link ContextConfiguration @ContextConfiguration} annotation, either explicitly
|
||||
* or implicitly.
|
||||
* @return the declaring class (never {@code null})
|
||||
*/
|
||||
public Class<?> getDeclaringClass() {
|
||||
|
|
|
@ -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.
|
||||
|
@ -29,7 +29,6 @@ import org.springframework.test.context.ContextLoader;
|
|||
import org.springframework.test.context.MergedContextConfiguration;
|
||||
import org.springframework.test.context.SmartContextLoader;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* {@code AbstractDelegatingSmartContextLoader} serves as an abstract base class
|
||||
|
@ -202,15 +201,6 @@ public abstract class AbstractDelegatingSmartContextLoader implements SmartConte
|
|||
name(getAnnotationConfigLoader()), configAttributes));
|
||||
}
|
||||
|
||||
// If neither loader detected defaults and no initializers were declared,
|
||||
// throw an exception.
|
||||
if (!configAttributes.hasResources() && ObjectUtils.isEmpty(configAttributes.getInitializers())) {
|
||||
throw new IllegalStateException(String.format(
|
||||
"Neither %s nor %s was able to detect defaults, and no ApplicationContextInitializers "
|
||||
+ "were declared for context configuration %s", name(getXmlLoader()),
|
||||
name(getAnnotationConfigLoader()), configAttributes));
|
||||
}
|
||||
|
||||
if (configAttributes.hasLocations() && configAttributes.hasClasses()) {
|
||||
String message = String.format(
|
||||
"Configuration error: both default locations AND default configuration classes "
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.test.context.support;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
|
@ -30,8 +31,6 @@ import org.apache.commons.logging.LogFactory;
|
|||
|
||||
import org.springframework.beans.BeanInstantiationException;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
|
@ -71,6 +70,7 @@ import org.springframework.util.StringUtils;
|
|||
*
|
||||
* @author Sam Brannen
|
||||
* @author Juergen Hoeller
|
||||
* @author Phillip Webb
|
||||
* @since 4.1
|
||||
*/
|
||||
public abstract class AbstractTestContextBootstrapper implements TestContextBootstrapper {
|
||||
|
@ -272,13 +272,8 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate = getCacheAwareContextLoaderDelegate();
|
||||
|
||||
if (MetaAnnotationUtils.findAnnotationDescriptorForTypes(testClass, ContextConfiguration.class,
|
||||
ContextHierarchy.class) == null) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(String.format(
|
||||
"Neither @ContextConfiguration nor @ContextHierarchy found for test class [%s]",
|
||||
testClass.getName()));
|
||||
}
|
||||
return new MergedContextConfiguration(testClass, null, null, null, null);
|
||||
ContextHierarchy.class) == null) {
|
||||
return buildDefaultMergedContextConfiguration(testClass, cacheAwareContextLoaderDelegate);
|
||||
}
|
||||
|
||||
if (AnnotationUtils.findAnnotation(testClass, ContextHierarchy.class) != null) {
|
||||
|
@ -297,7 +292,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||
Class<?> declaringClass = reversedList.get(0).getDeclaringClass();
|
||||
|
||||
mergedConfig = buildMergedContextConfiguration(declaringClass, reversedList, parentConfig,
|
||||
cacheAwareContextLoaderDelegate);
|
||||
cacheAwareContextLoaderDelegate, true);
|
||||
parentConfig = mergedConfig;
|
||||
}
|
||||
|
||||
|
@ -307,10 +302,29 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||
else {
|
||||
return buildMergedContextConfiguration(testClass,
|
||||
ContextLoaderUtils.resolveContextConfigurationAttributes(testClass), null,
|
||||
cacheAwareContextLoaderDelegate);
|
||||
cacheAwareContextLoaderDelegate, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
private MergedContextConfiguration buildDefaultMergedContextConfiguration(Class<?> testClass,
|
||||
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate) {
|
||||
|
||||
List<ContextConfigurationAttributes> defaultConfigAttributesList
|
||||
= Collections.singletonList(new ContextConfigurationAttributes(testClass));
|
||||
|
||||
ContextLoader contextLoader = resolveContextLoader(testClass, defaultConfigAttributesList);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(String.format(
|
||||
"Neither @ContextConfiguration nor @ContextHierarchy found for test class [%s], using %s",
|
||||
testClass.getName(), contextLoader.getClass().getSimpleName()));
|
||||
}
|
||||
return buildMergedContextConfiguration(testClass, defaultConfigAttributesList, null,
|
||||
cacheAwareContextLoaderDelegate, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the {@link MergedContextConfiguration merged context configuration}
|
||||
* for the supplied {@link Class testClass}, context configuration attributes,
|
||||
|
@ -324,6 +338,9 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||
* context in a context hierarchy, or {@code null} if there is no parent
|
||||
* @param cacheAwareContextLoaderDelegate the cache-aware context loader delegate to
|
||||
* be passed to the {@code MergedContextConfiguration} constructor
|
||||
* @param requireLocationsClassesOrInitializers whether locations, classes, or
|
||||
* initializers are required; typically {@code true} but may be set to {@code false}
|
||||
* if the configured loader supports empty configuration
|
||||
* @return the merged context configuration
|
||||
* @see #resolveContextLoader
|
||||
* @see ContextLoaderUtils#resolveContextConfigurationAttributes
|
||||
|
@ -335,11 +352,15 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||
*/
|
||||
private MergedContextConfiguration buildMergedContextConfiguration(Class<?> testClass,
|
||||
List<ContextConfigurationAttributes> configAttributesList, MergedContextConfiguration parentConfig,
|
||||
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate) {
|
||||
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate,
|
||||
boolean requireLocationsClassesOrInitializers) {
|
||||
|
||||
Assert.notEmpty(configAttributesList, "ContextConfigurationAttributes list must not be null or empty");
|
||||
|
||||
ContextLoader contextLoader = resolveContextLoader(testClass, configAttributesList);
|
||||
List<String> locationsList = new ArrayList<String>();
|
||||
List<Class<?>> classesList = new ArrayList<Class<?>>();
|
||||
List<String> locations = new ArrayList<String>();
|
||||
List<Class<?>> classes = new ArrayList<Class<?>>();
|
||||
List<Class<?>> initializers = new ArrayList<Class<?>>();
|
||||
|
||||
for (ContextConfigurationAttributes configAttributes : configAttributesList) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
|
@ -349,34 +370,53 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||
if (contextLoader instanceof SmartContextLoader) {
|
||||
SmartContextLoader smartContextLoader = (SmartContextLoader) contextLoader;
|
||||
smartContextLoader.processContextConfiguration(configAttributes);
|
||||
locationsList.addAll(0, Arrays.asList(configAttributes.getLocations()));
|
||||
classesList.addAll(0, Arrays.asList(configAttributes.getClasses()));
|
||||
locations.addAll(0, Arrays.asList(configAttributes.getLocations()));
|
||||
classes.addAll(0, Arrays.asList(configAttributes.getClasses()));
|
||||
}
|
||||
else {
|
||||
String[] processedLocations = contextLoader.processLocations(configAttributes.getDeclaringClass(),
|
||||
configAttributes.getLocations());
|
||||
locationsList.addAll(0, Arrays.asList(processedLocations));
|
||||
String[] processedLocations = contextLoader.processLocations(
|
||||
configAttributes.getDeclaringClass(), configAttributes.getLocations());
|
||||
locations.addAll(0, Arrays.asList(processedLocations));
|
||||
// Legacy ContextLoaders don't know how to process classes
|
||||
}
|
||||
initializers.addAll(0, Arrays.asList(configAttributes.getInitializers()));
|
||||
if (!configAttributes.isInheritLocations()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
String[] locations = StringUtils.toStringArray(locationsList);
|
||||
Class<?>[] classes = ClassUtils.toClassArray(classesList);
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> initializerClasses = //
|
||||
ApplicationContextInitializerUtils.resolveInitializerClasses(configAttributesList);
|
||||
String[] activeProfiles = ActiveProfilesUtils.resolveActiveProfiles(testClass);
|
||||
MergedTestPropertySources mergedTestPropertySources = TestPropertySourceUtils.buildMergedTestPropertySources(testClass);
|
||||
if (requireLocationsClassesOrInitializers && areAllEmpty(locations, classes, initializers)) {
|
||||
throw new IllegalStateException(String.format(
|
||||
"%s was unable to detect defaults, and no ApplicationContextInitializers "
|
||||
+ "were declared for context configuration attributes %s",
|
||||
contextLoader.getClass().getSimpleName(), configAttributesList));
|
||||
}
|
||||
|
||||
MergedContextConfiguration mergedConfig = new MergedContextConfiguration(testClass, locations, classes,
|
||||
initializerClasses, activeProfiles, mergedTestPropertySources.getLocations(),
|
||||
mergedTestPropertySources.getProperties(), contextLoader, cacheAwareContextLoaderDelegate, parentConfig);
|
||||
MergedTestPropertySources mergedTestPropertySources = TestPropertySourceUtils.buildMergedTestPropertySources(testClass);
|
||||
MergedContextConfiguration mergedConfig = new MergedContextConfiguration(testClass,
|
||||
StringUtils.toStringArray(locations),
|
||||
ClassUtils.toClassArray(classes),
|
||||
ApplicationContextInitializerUtils.resolveInitializerClasses(configAttributesList),
|
||||
ActiveProfilesUtils.resolveActiveProfiles(testClass),
|
||||
mergedTestPropertySources.getLocations(),
|
||||
mergedTestPropertySources.getProperties(),
|
||||
contextLoader, cacheAwareContextLoaderDelegate, parentConfig);
|
||||
|
||||
return processMergedContextConfiguration(mergedConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
private boolean areAllEmpty(Collection<?>... collections) {
|
||||
for (Collection<?> collection : collections) {
|
||||
if (!collection.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the {@link ContextLoader} {@linkplain Class class} to use for the
|
||||
* supplied list of {@link ContextConfigurationAttributes} and then instantiate
|
||||
|
@ -389,7 +429,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||
* @param testClass the test class for which the {@code ContextLoader} should be
|
||||
* resolved; must not be {@code null}
|
||||
* @param configAttributesList the list of configuration attributes to process; must
|
||||
* not be {@code null} or <em>empty</em>; must be ordered <em>bottom-up</em>
|
||||
* not be {@code null}; must be ordered <em>bottom-up</em>
|
||||
* (i.e., as if we were traversing up the class hierarchy)
|
||||
* @return the resolved {@code ContextLoader} for the supplied {@code testClass}
|
||||
* (never {@code null})
|
||||
|
@ -400,7 +440,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||
List<ContextConfigurationAttributes> configAttributesList) {
|
||||
|
||||
Assert.notNull(testClass, "Class must not be null");
|
||||
Assert.notEmpty(configAttributesList, "ContextConfigurationAttributes list must not be empty");
|
||||
Assert.notNull(configAttributesList, "ContextConfigurationAttributes list must not be null");
|
||||
|
||||
Class<? extends ContextLoader> contextLoaderClass = resolveExplicitContextLoaderClass(configAttributesList);
|
||||
if (contextLoaderClass == null) {
|
||||
|
@ -429,7 +469,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||
* step #1.</li>
|
||||
* </ol>
|
||||
* @param configAttributesList the list of configuration attributes to process;
|
||||
* must not be {@code null} or <em>empty</em>; must be ordered <em>bottom-up</em>
|
||||
* must not be {@code null}; must be ordered <em>bottom-up</em>
|
||||
* (i.e., as if we were traversing up the class hierarchy)
|
||||
* @return the {@code ContextLoader} class to use for the supplied configuration
|
||||
* attributes, or {@code null} if no explicit loader is found
|
||||
|
@ -439,7 +479,8 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||
protected Class<? extends ContextLoader> resolveExplicitContextLoaderClass(
|
||||
List<ContextConfigurationAttributes> configAttributesList) {
|
||||
|
||||
Assert.notEmpty(configAttributesList, "ContextConfigurationAttributes list must not be empty");
|
||||
Assert.notNull(configAttributesList, "ContextConfigurationAttributes list must not be null");
|
||||
|
||||
for (ContextConfigurationAttributes configAttributes : configAttributesList) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace(String.format("Resolving ContextLoader for context configuration attributes %s",
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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.junit4;
|
||||
|
||||
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 static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* JUnit 4 based integration test which verifies that {@link @ContextConfiguration}
|
||||
* is optional.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Sam Brannen
|
||||
* @since 4.3
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
public class OptionalContextConfigurationSpringRunnerTests {
|
||||
|
||||
@Autowired
|
||||
String foo;
|
||||
|
||||
|
||||
@Test
|
||||
public void contextConfigurationAnnotationIsOptional() {
|
||||
assertEquals("foo", foo);
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
String foo() {
|
||||
return "foo";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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.
|
||||
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.springframework.test.context.support;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -35,63 +36,62 @@ import org.springframework.web.context.support.GenericWebApplicationContext;
|
|||
* @author Sam Brannen
|
||||
* @since 3.1
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class BootstrapTestUtilsContextInitializerTests extends AbstractContextConfigurationUtilsTests {
|
||||
|
||||
@Test
|
||||
public void buildMergedConfigWithLocalInitializer() {
|
||||
Class<?> testClass = InitializersFoo.class;
|
||||
Class<?>[] expectedClasses = new Class<?>[] { FooConfig.class };
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> expectedInitializerClasses//
|
||||
= new HashSet<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>>();
|
||||
expectedInitializerClasses.add(FooInitializer.class);
|
||||
|
||||
public void buildMergedConfigWithSingleLocalInitializer() {
|
||||
Class<?> testClass = SingleInitializer.class;
|
||||
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass);
|
||||
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, expectedClasses, expectedInitializerClasses,
|
||||
DelegatingSmartContextLoader.class);
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY,
|
||||
initializers(FooInitializer.class), DelegatingSmartContextLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildMergedConfigWithLocalInitializerAndConfigClass() {
|
||||
Class<?> testClass = InitializersFoo.class;
|
||||
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass);
|
||||
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, classes(FooConfig.class),
|
||||
initializers(FooInitializer.class), DelegatingSmartContextLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildMergedConfigWithLocalAndInheritedInitializer() {
|
||||
Class<?> testClass = InitializersBar.class;
|
||||
Class<?>[] expectedClasses = new Class<?>[] { FooConfig.class, BarConfig.class };
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> expectedInitializerClasses//
|
||||
= new HashSet<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>>();
|
||||
expectedInitializerClasses.add(FooInitializer.class);
|
||||
expectedInitializerClasses.add(BarInitializer.class);
|
||||
|
||||
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass);
|
||||
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, expectedClasses, expectedInitializerClasses,
|
||||
DelegatingSmartContextLoader.class);
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, classes(FooConfig.class, BarConfig.class),
|
||||
initializers(FooInitializer.class, BarInitializer.class), DelegatingSmartContextLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildMergedConfigWithOverriddenInitializers() {
|
||||
Class<?> testClass = OverriddenInitializersBar.class;
|
||||
Class<?>[] expectedClasses = new Class<?>[] { FooConfig.class, BarConfig.class };
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> expectedInitializerClasses//
|
||||
= new HashSet<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>>();
|
||||
expectedInitializerClasses.add(BarInitializer.class);
|
||||
|
||||
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass);
|
||||
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, expectedClasses, expectedInitializerClasses,
|
||||
DelegatingSmartContextLoader.class);
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, classes(FooConfig.class, BarConfig.class),
|
||||
initializers(BarInitializer.class), DelegatingSmartContextLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildMergedConfigWithOverriddenInitializersAndClasses() {
|
||||
Class<?> testClass = OverriddenInitializersAndClassesBar.class;
|
||||
Class<?>[] expectedClasses = new Class<?>[] { BarConfig.class };
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> expectedInitializerClasses//
|
||||
= new HashSet<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>>();
|
||||
expectedInitializerClasses.add(BarInitializer.class);
|
||||
|
||||
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass);
|
||||
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, expectedClasses, expectedInitializerClasses,
|
||||
DelegatingSmartContextLoader.class);
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, classes(BarConfig.class),
|
||||
initializers(BarInitializer.class), DelegatingSmartContextLoader.class);
|
||||
}
|
||||
|
||||
private Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> initializers(
|
||||
Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>... classes) {
|
||||
|
||||
return new HashSet<>(Arrays.asList(classes));
|
||||
}
|
||||
|
||||
private Class<?>[] classes(Class<?>... classes) {
|
||||
return classes;
|
||||
}
|
||||
|
||||
|
||||
|
@ -109,6 +109,10 @@ public class BootstrapTestUtilsContextInitializerTests extends AbstractContextCo
|
|||
}
|
||||
}
|
||||
|
||||
@ContextConfiguration(initializers = FooInitializer.class)
|
||||
private static class SingleInitializer {
|
||||
}
|
||||
|
||||
@ContextConfiguration(classes = FooConfig.class, initializers = FooInitializer.class)
|
||||
private static class InitializersFoo {
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
@ -21,15 +21,20 @@ import java.lang.annotation.Retention;
|
|||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.test.context.BootstrapTestUtils;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.ContextLoader;
|
||||
import org.springframework.test.context.MergedContextConfiguration;
|
||||
import org.springframework.test.context.web.WebDelegatingSmartContextLoader;
|
||||
import org.springframework.test.context.web.WebMergedContextConfiguration;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.CoreMatchers.startsWith;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link BootstrapTestUtils} involving {@link MergedContextConfiguration}.
|
||||
|
@ -39,12 +44,28 @@ import static org.junit.Assert.*;
|
|||
*/
|
||||
public class BootstrapTestUtilsMergedConfigTests extends AbstractContextConfigurationUtilsTests {
|
||||
|
||||
@Rule
|
||||
public final ExpectedException exception = ExpectedException.none();
|
||||
|
||||
|
||||
@Test
|
||||
public void buildMergedConfigWithoutAnnotation() {
|
||||
public void buildImplicitMergedConfigWithoutAnnotation() {
|
||||
Class<?> testClass = Enigma.class;
|
||||
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass);
|
||||
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, null);
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, DelegatingSmartContextLoader.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
@Test
|
||||
public void buildMergedConfigWithContextConfigurationWithoutLocationsClassesOrInitializers() {
|
||||
exception.expect(IllegalStateException.class);
|
||||
exception.expectMessage(startsWith("DelegatingSmartContextLoader was unable to detect defaults, "
|
||||
+ "and no ApplicationContextInitializers were declared for context configuration attributes"));
|
||||
|
||||
buildMergedContextConfiguration(MissingContextAttributesTestCase.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -200,4 +221,8 @@ public class BootstrapTestUtilsMergedConfigTests extends AbstractContextConfigur
|
|||
public static class GermanShepherd extends WorkingDog {
|
||||
}
|
||||
|
||||
@ContextConfiguration
|
||||
static class MissingContextAttributesTestCase {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
@ -55,17 +55,6 @@ public class DelegatingSmartContextLoaderTests {
|
|||
|
||||
// --- SmartContextLoader - processContextConfiguration() ------------------
|
||||
|
||||
@Test
|
||||
public void processContextConfigurationWithoutLocationsAndConfigurationClassesForBogusTestClass() {
|
||||
expectedException.expect(IllegalStateException.class);
|
||||
expectedException.expectMessage(startsWith("Neither"));
|
||||
expectedException.expectMessage(containsString("was able to detect defaults"));
|
||||
|
||||
ContextConfigurationAttributes configAttributes = new ContextConfigurationAttributes(getClass(),
|
||||
EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, true, null, true, ContextLoader.class);
|
||||
loader.processContextConfiguration(configAttributes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processContextConfigurationWithDefaultXmlConfigGeneration() {
|
||||
ContextConfigurationAttributes configAttributes = new ContextConfigurationAttributes(XmlTestCase.class,
|
||||
|
|
|
@ -686,6 +686,8 @@ Spring 4.3 also improves the caching abstraction as follows:
|
|||
|
||||
* The JUnit support in the _Spring TestContext Framework_ now requires JUnit 4.12 or higher.
|
||||
* New `SpringRunner` __alias__ for the `SpringJUnit4ClassRunner`.
|
||||
* An empty declaration of `@ContextConfiguration` can now be completely omitted if default
|
||||
XML files, Groovy scripts, or `@Configuration` classes are detected.
|
||||
* `@BeforeTransaction` and `@AfterTransaction` methods are no longer required to be `public`.
|
||||
* Server-side Spring MVC Test supports expectations on response headers with multiple values.
|
||||
* Server-side Spring MVC Test parses form data request content and populates request parameters.
|
||||
|
|
Loading…
Reference in New Issue