Support ApplicationContextInitializers in the TCF
Starting with Spring 3.1 applications can specify contextInitializerClasses via context-param and init-param in web.xml; however, there is currently no way to have such initializers invoked in integration testing scenarios without writing a custom SmartContextLoader. For comprehensive integration testing it should therefore be possible to re-use ApplicationContextInitializers in the Spring TestContext Framework as well. This commit makes this possible at the @ContextConfiguration level by allowing an array of ACI types to be specified, and the out-of-the-box SmartContextLoader implementations invoke the declared initializers at the appropriate time. - Added initializers and inheritInitializers attributes to @ContextConfiguration. - Introduced support for ApplicationContextInitializers in ContextConfigurationAttributes, MergedContextConfiguration, and ContextLoaderUtils. - MergedContextConfiguration stores context initializer classes as a Set and incorporates them into the implementations of hashCode() and equals() for proper context caching. - ApplicationContextInitializers are invoked in the new prepareContext(GenericApplicationContext, MergedContextConfiguration) method in AbstractGenericContextLoader, and ordering declared via the Ordered interface and @Order annotation is honored. - Updated DelegatingSmartContextLoader to support initializers. Specifically, a test class may optionally declare neither XML configuration files nor annotated classes and instead declare only application context initializers. In such cases, an attempt will still be made to detect defaults, but their absence will not result an an exception. - Documented support for application context initializers in Javadoc and in the testing chapter of the reference manual. Issue: SPR-9011
This commit is contained in:
parent
9c8c967caa
commit
1f93777bbd
|
@ -1,13 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beansProjectDescription>
|
||||
<version>1</version>
|
||||
<pluginVersion><![CDATA[2.6.0.201104111100-PATCH]]></pluginVersion>
|
||||
<pluginVersion><![CDATA[3.0.0.201208090952-RELEASE]]></pluginVersion>
|
||||
<configSuffixes>
|
||||
<configSuffix><![CDATA[xml]]></configSuffix>
|
||||
</configSuffixes>
|
||||
<enableImports><![CDATA[false]]></enableImports>
|
||||
<configs>
|
||||
<config>src/test/java/org/springframework/test/context/junit4/profile/xml/DefaultProfileXmlConfigTests-context.xml</config>
|
||||
<config>src/test/java/org/springframework/test/context/junit4/aci/xml/MultipleInitializersXmlConfigTests-context.xml</config>
|
||||
</configs>
|
||||
<configSets>
|
||||
</configSets>
|
||||
|
|
|
@ -23,19 +23,19 @@ 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.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
/**
|
||||
* {@code ContextConfiguration} defines class-level metadata that is
|
||||
* {@code @ContextConfiguration} defines class-level metadata that is
|
||||
* used to determine how to load and configure an
|
||||
* {@link org.springframework.context.ApplicationContext ApplicationContext}
|
||||
* for test classes.
|
||||
* for integration tests.
|
||||
*
|
||||
* <h3>Supported Resource Types</h3>
|
||||
*
|
||||
* <p>Prior to Spring 3.1, only path-based resource locations were supported.
|
||||
* As of Spring 3.1, {@link #loader context loaders} may choose to support
|
||||
* As of Spring 3.1, {@linkplain #loader context loaders} may choose to support
|
||||
* either path-based or class-based resources (but not both). Consequently
|
||||
* {@code @ContextConfiguration} can be used to declare either path-based
|
||||
* resource locations (via the {@link #locations} or {@link #value}
|
||||
|
@ -47,16 +47,20 @@ import org.springframework.context.annotation.Configuration;
|
|||
* <p>The term <em>annotated class</em> can refer to any of the following.
|
||||
*
|
||||
* <ul>
|
||||
* <li>A class annotated with {@link Configuration @Configuration}</li>
|
||||
* <li>A class annotated with
|
||||
* {@link org.springframework.context.annotation.Configuration @Configuration}</li>
|
||||
* <li>A component (i.e., a class annotated with
|
||||
* {@link org.springframework.stereotype.Component @Component},
|
||||
* {@link org.springframework.stereotype.Service @Service},
|
||||
* {@link org.springframework.stereotype.Repository @Repository}, etc.)</li>
|
||||
* <li>A JSR-330 compliant class that is annotated with {@code javax.inject} annotations</li>
|
||||
* <li>Any other class that contains {@link Bean @Bean}-methods</li>
|
||||
* <li>Any other class that contains
|
||||
* {@link org.springframework.context.annotation.Bean @Bean}-methods</li>
|
||||
* </ul>
|
||||
*
|
||||
* Consult the JavaDoc for {@link Configuration @Configuration} and {@link Bean @Bean}
|
||||
* Consult the Javadoc for
|
||||
* {@link org.springframework.context.annotation.Configuration @Configuration} and
|
||||
* {@link org.springframework.context.annotation.Bean @Bean}
|
||||
* for further information regarding the configuration and semantics of
|
||||
* <em>annotated classes</em>.
|
||||
*
|
||||
|
@ -66,8 +70,8 @@ import org.springframework.context.annotation.Configuration;
|
|||
* @see SmartContextLoader
|
||||
* @see ContextConfigurationAttributes
|
||||
* @see MergedContextConfiguration
|
||||
* @see org.springframework.context.ApplicationContext
|
||||
* @see ActiveProfiles
|
||||
* @see org.springframework.context.ApplicationContext
|
||||
*/
|
||||
@Documented
|
||||
@Inherited
|
||||
|
@ -82,6 +86,7 @@ public @interface ContextConfiguration {
|
|||
* with {@link #locations} or {@link #classes}, but it may be used
|
||||
* instead of {@link #locations}.
|
||||
* @since 3.0
|
||||
* @see #inheritLocations
|
||||
*/
|
||||
String[] value() default {};
|
||||
|
||||
|
@ -111,6 +116,7 @@ public @interface ContextConfiguration {
|
|||
* {@link #value} or {@link #classes}, but it may be used instead of
|
||||
* {@link #value}.
|
||||
* @since 2.5
|
||||
* @see #inheritLocations
|
||||
*/
|
||||
String[] locations() default {};
|
||||
|
||||
|
@ -131,9 +137,31 @@ public @interface ContextConfiguration {
|
|||
* @since 3.1
|
||||
* @see org.springframework.context.annotation.Configuration
|
||||
* @see org.springframework.test.context.support.AnnotationConfigContextLoader
|
||||
* @see #inheritLocations
|
||||
*/
|
||||
Class<?>[] classes() default {};
|
||||
|
||||
/**
|
||||
* The application context <em>initializer classes</em> to use for initializing
|
||||
* a {@link ConfigurableApplicationContext}.
|
||||
*
|
||||
* <p>The concrete {@code ConfigurableApplicationContext} type supported by each
|
||||
* declared initializer must be compatible with the type of {@code ApplicationContext}
|
||||
* created by the {@link SmartContextLoader} in use.
|
||||
*
|
||||
* <p>{@code SmartContextLoader} implementations typically detect whether
|
||||
* Spring's {@link org.springframework.core.Ordered Ordered} interface has been
|
||||
* implemented or if the @{@link org.springframework.core.annotation.Order Order}
|
||||
* annotation is present and sort instances accordingly prior to invoking them.
|
||||
*
|
||||
* @since 3.2
|
||||
* @see org.springframework.context.ApplicationContextInitializer
|
||||
* @see org.springframework.context.ConfigurableApplicationContext
|
||||
* @see #inheritInitializers
|
||||
* @see #loader
|
||||
*/
|
||||
Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>[] initializers() default {};
|
||||
|
||||
/**
|
||||
* Whether or not {@link #locations resource locations} or <em>annotated
|
||||
* classes</em> from test superclasses should be <em>inherited</em>.
|
||||
|
@ -194,7 +222,45 @@ public @interface ContextConfiguration {
|
|||
boolean inheritLocations() default true;
|
||||
|
||||
/**
|
||||
* The type of {@link ContextLoader} (or {@link SmartContextLoader}) to use
|
||||
* Whether or not {@linkplain #initializers context initializers} from test
|
||||
* superclasses should be <em>inherited</em>.
|
||||
*
|
||||
* <p>The default value is <code>true</code>. This means that an annotated
|
||||
* class will <em>inherit</em> the application context initializers defined
|
||||
* by test superclasses. Specifically, the initializers for a given test
|
||||
* class will be added to the set of initializers defined by test
|
||||
* superclasses. Thus, subclasses have the option of <em>extending</em> the
|
||||
* set of initializers.
|
||||
*
|
||||
* <p>If <code>inheritInitializers</code> is set to <code>false</code>, the
|
||||
* initializers for the annotated class will <em>shadow</em> and effectively
|
||||
* replace any initializers defined by superclasses.
|
||||
*
|
||||
* <p>In the following example, the
|
||||
* {@link org.springframework.context.ApplicationContext ApplicationContext}
|
||||
* for {@code ExtendedTest} will be initialized using
|
||||
* {@code BaseInitializer} <strong>and</strong> {@code ExtendedInitializer}.
|
||||
* Note, however, that the order in which the initializers are invoked
|
||||
* depends on whether they implement {@link org.springframework.core.Ordered
|
||||
* Ordered} or are annotated with {@link org.springframework.core.annotation.Order
|
||||
* @Order}.
|
||||
* <pre class="code">
|
||||
* @ContextConfiguration(initializers = BaseInitializer.class)
|
||||
* public class BaseTest {
|
||||
* // ...
|
||||
* }
|
||||
*
|
||||
* @ContextConfiguration(initializers = ExtendedInitializer.class)
|
||||
* public class ExtendedTest extends BaseTest {
|
||||
* // ...
|
||||
* }
|
||||
* </pre>
|
||||
* @since 3.2
|
||||
*/
|
||||
boolean inheritInitializers() default true;
|
||||
|
||||
/**
|
||||
* The type of {@link SmartContextLoader} (or {@link ContextLoader}) to use
|
||||
* for loading an {@link org.springframework.context.ApplicationContext
|
||||
* ApplicationContext}.
|
||||
*
|
||||
|
|
|
@ -18,12 +18,15 @@ package org.springframework.test.context;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* <code>ContextConfigurationAttributes</code> encapsulates the context
|
||||
* {@code ContextConfigurationAttributes} encapsulates the context
|
||||
* configuration attributes declared on a test class via
|
||||
* {@link ContextConfiguration @ContextConfiguration}.
|
||||
*
|
||||
|
@ -47,6 +50,10 @@ public class ContextConfigurationAttributes {
|
|||
|
||||
private final Class<? extends ContextLoader> contextLoaderClass;
|
||||
|
||||
private final Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>[] initializers;
|
||||
|
||||
private final boolean inheritInitializers;
|
||||
|
||||
|
||||
/**
|
||||
* Resolve resource locations from the {@link ContextConfiguration#locations() locations}
|
||||
|
@ -68,8 +75,7 @@ public class ContextConfigurationAttributes {
|
|||
ObjectUtils.nullSafeToString(valueLocations), ObjectUtils.nullSafeToString(locations));
|
||||
logger.error(msg);
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
else if (!ObjectUtils.isEmpty(valueLocations)) {
|
||||
} else if (!ObjectUtils.isEmpty(valueLocations)) {
|
||||
locations = valueLocations;
|
||||
}
|
||||
|
||||
|
@ -79,31 +85,59 @@ public class ContextConfigurationAttributes {
|
|||
/**
|
||||
* Construct a new {@link ContextConfigurationAttributes} instance for the
|
||||
* supplied {@link ContextConfiguration @ContextConfiguration} annotation and
|
||||
* the {@link Class test class} that declared it.
|
||||
* the {@linkplain Class test class} that declared it.
|
||||
* @param declaringClass the test class that declared {@code @ContextConfiguration}
|
||||
* @param contextConfiguration the annotation from which to retrieve the attributes
|
||||
*/
|
||||
public ContextConfigurationAttributes(Class<?> declaringClass, ContextConfiguration contextConfiguration) {
|
||||
this(declaringClass, resolveLocations(declaringClass, contextConfiguration), contextConfiguration.classes(),
|
||||
contextConfiguration.inheritLocations(), contextConfiguration.loader());
|
||||
contextConfiguration.inheritLocations(), contextConfiguration.initializers(),
|
||||
contextConfiguration.inheritInitializers(), contextConfiguration.loader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@link ContextConfigurationAttributes} instance for the
|
||||
* {@link Class test class} that declared the
|
||||
* {@linkplain Class test class} that declared the
|
||||
* {@link ContextConfiguration @ContextConfiguration} annotation and its
|
||||
* corresponding attributes.
|
||||
*
|
||||
* @param declaringClass the test class that declared {@code @ContextConfiguration}
|
||||
* @param locations the resource locations declared via {@code @ContextConfiguration}
|
||||
* @param classes the annotated classes declared via {@code @ContextConfiguration}
|
||||
* @param inheritLocations the <code>inheritLocations</code> flag declared via {@code @ContextConfiguration}
|
||||
* @param inheritLocations the {@code inheritLocations} flag declared via {@code @ContextConfiguration}
|
||||
* @param contextLoaderClass the {@code ContextLoader} class declared via {@code @ContextConfiguration}
|
||||
* @throws IllegalArgumentException if the {@code declaringClass} or {@code contextLoaderClass} is
|
||||
* <code>null</code>, or if the {@code locations} and {@code classes} are both non-empty
|
||||
* {@code null}, or if the {@code locations} and {@code classes} are both non-empty
|
||||
* @deprecated as of Spring 3.2, use
|
||||
* {@link #ContextConfigurationAttributes(Class, String[], Class[], boolean, Class[], boolean, Class)}
|
||||
* instead
|
||||
*/
|
||||
@Deprecated
|
||||
public ContextConfigurationAttributes(Class<?> declaringClass, String[] locations, Class<?>[] classes,
|
||||
boolean inheritLocations, Class<? extends ContextLoader> contextLoaderClass) {
|
||||
this(declaringClass, locations, classes, inheritLocations, null, true, contextLoaderClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@link ContextConfigurationAttributes} instance for the
|
||||
* {@linkplain Class test class} that declared the
|
||||
* {@link ContextConfiguration @ContextConfiguration} annotation and its
|
||||
* corresponding attributes.
|
||||
*
|
||||
* @param declaringClass the test class that declared {@code @ContextConfiguration}
|
||||
* @param locations the resource locations declared via {@code @ContextConfiguration}
|
||||
* @param classes the annotated classes declared via {@code @ContextConfiguration}
|
||||
* @param inheritLocations the {@code inheritLocations} flag declared via {@code @ContextConfiguration}
|
||||
* @param initializers the context initializers declared via {@code @ContextConfiguration}
|
||||
* @param inheritInitializers the {@code inheritInitializers} flag declared via {@code @ContextConfiguration}
|
||||
* @param contextLoaderClass the {@code ContextLoader} class declared via {@code @ContextConfiguration}
|
||||
* @throws IllegalArgumentException if the {@code declaringClass} or {@code contextLoaderClass} is
|
||||
* {@code null}, or if the {@code locations} and {@code classes} are both non-empty
|
||||
*/
|
||||
public ContextConfigurationAttributes(Class<?> declaringClass, String[] locations, Class<?>[] classes,
|
||||
boolean inheritLocations,
|
||||
Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>[] initializers,
|
||||
boolean inheritInitializers, Class<? extends ContextLoader> contextLoaderClass) {
|
||||
|
||||
Assert.notNull(declaringClass, "declaringClass must not be null");
|
||||
Assert.notNull(contextLoaderClass, "contextLoaderClass must not be null");
|
||||
|
@ -122,14 +156,16 @@ public class ContextConfigurationAttributes {
|
|||
this.locations = locations;
|
||||
this.classes = classes;
|
||||
this.inheritLocations = inheritLocations;
|
||||
this.initializers = initializers;
|
||||
this.inheritInitializers = inheritInitializers;
|
||||
this.contextLoaderClass = contextLoaderClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Class class} that declared the
|
||||
* Get the {@linkplain Class class} that declared the
|
||||
* {@link ContextConfiguration @ContextConfiguration} annotation.
|
||||
*
|
||||
* @return the declaring class; never <code>null</code>
|
||||
* @return the declaring class; never {@code null}
|
||||
*/
|
||||
public Class<?> getDeclaringClass() {
|
||||
return declaringClass;
|
||||
|
@ -143,7 +179,7 @@ public class ContextConfigurationAttributes {
|
|||
* represent a <em>processed</em> value that does not match the original value
|
||||
* declared via {@link ContextConfiguration @ContextConfiguration}.
|
||||
*
|
||||
* @return the resource locations; potentially <code>null</code> or <em>empty</em>
|
||||
* @return the resource locations; potentially {@code null} or <em>empty</em>
|
||||
* @see ContextConfiguration#value
|
||||
* @see ContextConfiguration#locations
|
||||
* @see #setLocations(String[])
|
||||
|
@ -170,7 +206,7 @@ public class ContextConfigurationAttributes {
|
|||
* represent a <em>processed</em> value that does not match the original value
|
||||
* declared via {@link ContextConfiguration @ContextConfiguration}.
|
||||
*
|
||||
* @return the annotated classes; potentially <code>null</code> or <em>empty</em>
|
||||
* @return the annotated classes; potentially {@code null} or <em>empty</em>
|
||||
* @see ContextConfiguration#classes
|
||||
* @see #setClasses(Class[])
|
||||
*/
|
||||
|
@ -192,7 +228,7 @@ public class ContextConfigurationAttributes {
|
|||
* Determine if this {@code ContextConfigurationAttributes} instance has
|
||||
* path-based resource locations.
|
||||
*
|
||||
* @return <code>true</code> if the {@link #getLocations() locations} array is not empty
|
||||
* @return {@code true} if the {@link #getLocations() locations} array is not empty
|
||||
* @see #hasResources()
|
||||
* @see #hasClasses()
|
||||
*/
|
||||
|
@ -204,7 +240,7 @@ public class ContextConfigurationAttributes {
|
|||
* Determine if this {@code ContextConfigurationAttributes} instance has
|
||||
* class-based resources.
|
||||
*
|
||||
* @return <code>true</code> if the {@link #getClasses() classes} array is not empty
|
||||
* @return {@code true} if the {@link #getClasses() classes} array is not empty
|
||||
* @see #hasResources()
|
||||
* @see #hasLocations()
|
||||
*/
|
||||
|
@ -216,7 +252,7 @@ public class ContextConfigurationAttributes {
|
|||
* Determine if this {@code ContextConfigurationAttributes} instance has
|
||||
* either path-based resource locations or class-based resources.
|
||||
*
|
||||
* @return <code>true</code> if either the {@link #getLocations() locations}
|
||||
* @return {@code true} if either the {@link #getLocations() locations}
|
||||
* or the {@link #getClasses() classes} array is not empty
|
||||
* @see #hasLocations()
|
||||
* @see #hasClasses()
|
||||
|
@ -226,10 +262,10 @@ public class ContextConfigurationAttributes {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the <code>inheritLocations</code> flag that was declared via
|
||||
* Get the {@code inheritLocations} flag that was declared via
|
||||
* {@link ContextConfiguration @ContextConfiguration}.
|
||||
*
|
||||
* @return the <code>inheritLocations</code> flag
|
||||
* @return the {@code inheritLocations} flag
|
||||
* @see ContextConfiguration#inheritLocations
|
||||
*/
|
||||
public boolean isInheritLocations() {
|
||||
|
@ -237,10 +273,32 @@ public class ContextConfigurationAttributes {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the <code>ContextLoader</code> class that was declared via
|
||||
* Get the {@code ApplicationContextInitializer} classes that were declared via
|
||||
* {@link ContextConfiguration @ContextConfiguration}.
|
||||
*
|
||||
* @return the <code>ContextLoader</code> class
|
||||
* @return the {@code ApplicationContextInitializer} classes
|
||||
* @since 3.2
|
||||
*/
|
||||
public Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>[] getInitializers() {
|
||||
return initializers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@code inheritInitializers} flag that was declared via
|
||||
* {@link ContextConfiguration @ContextConfiguration}.
|
||||
*
|
||||
* @return the {@code inheritInitializers} flag
|
||||
* @since 3.2
|
||||
*/
|
||||
public boolean isInheritInitializers() {
|
||||
return inheritInitializers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@code ContextLoader} class that was declared via
|
||||
* {@link ContextConfiguration @ContextConfiguration}.
|
||||
*
|
||||
* @return the {@code ContextLoader} class
|
||||
* @see ContextConfiguration#loader
|
||||
*/
|
||||
public Class<? extends ContextLoader> getContextLoaderClass() {
|
||||
|
@ -258,6 +316,8 @@ public class ContextConfigurationAttributes {
|
|||
.append("locations", ObjectUtils.nullSafeToString(locations))//
|
||||
.append("classes", ObjectUtils.nullSafeToString(classes))//
|
||||
.append("inheritLocations", inheritLocations)//
|
||||
.append("initializers", ObjectUtils.nullSafeToString(initializers))//
|
||||
.append("inheritInitializers", inheritInitializers)//
|
||||
.append("contextLoaderClass", contextLoaderClass.getName())//
|
||||
.toString();
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@ import org.springframework.context.ApplicationContext;
|
|||
* for an integration test managed by the Spring TestContext Framework.
|
||||
*
|
||||
* <p><b>Note</b>: as of Spring 3.1, implement {@link SmartContextLoader} instead
|
||||
* of this interface in order to provide support for annotated classes and active
|
||||
* bean definition profiles.
|
||||
* of this interface in order to provide support for annotated classes, active
|
||||
* bean definition profiles, and application context initializers.
|
||||
*
|
||||
* <p>Clients of a ContextLoader should call
|
||||
* {@link #processLocations(Class,String...) processLocations()} prior to
|
||||
|
|
|
@ -21,12 +21,15 @@ import static org.springframework.core.annotation.AnnotationUtils.findAnnotation
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
@ -156,8 +159,7 @@ abstract class ContextLoaderUtils {
|
|||
}
|
||||
return (Class<? extends ContextLoader>) ContextLoaderUtils.class.getClassLoader().loadClass(
|
||||
defaultContextLoaderClassName);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
} catch (ClassNotFoundException ex) {
|
||||
throw new IllegalStateException("Could not load default ContextLoader class ["
|
||||
+ defaultContextLoaderClassName + "]. Specify @ContextConfiguration's 'loader' "
|
||||
+ "attribute or make the default loader class available.");
|
||||
|
@ -169,17 +171,15 @@ abstract class ContextLoaderUtils {
|
|||
* attributes} for the supplied {@link Class class} and its superclasses.
|
||||
*
|
||||
* <p>Note that the {@link ContextConfiguration#inheritLocations
|
||||
* inheritLocations} flag of {@link ContextConfiguration
|
||||
* @ContextConfiguration} will be taken into consideration.
|
||||
* Specifically, if the <code>inheritLocations</code> flag is set to
|
||||
* <code>true</code>, configuration attributes defined in the test
|
||||
* class will be appended to the configuration attributes defined in
|
||||
* superclasses.
|
||||
* inheritLocations} and {@link ContextConfiguration#inheritInitializers()
|
||||
* inheritInitializers} flags of {@link ContextConfiguration
|
||||
* @ContextConfiguration} will <strong>not</strong> be taken into
|
||||
* consideration. If these flags need to be honored, that must be handled
|
||||
* manually when traversing the list returned by this method.
|
||||
*
|
||||
* @param clazz the class for which to resolve the configuration attributes (must
|
||||
* not be <code>null</code>)
|
||||
* @return the list of configuration attributes for the specified class,
|
||||
* including configuration attributes from superclasses if appropriate
|
||||
* @return the list of configuration attributes for the specified class
|
||||
* (never <code>null</code>)
|
||||
* @throws IllegalArgumentException if the supplied class is <code>null</code> or
|
||||
* if {@code @ContextConfiguration} is not <em>present</em> on the supplied class
|
||||
|
@ -211,13 +211,69 @@ abstract class ContextLoaderUtils {
|
|||
|
||||
attributesList.add(0, attributes);
|
||||
|
||||
declaringClass = contextConfiguration.inheritLocations() ? findAnnotationDeclaringClass(annotationType,
|
||||
declaringClass.getSuperclass()) : null;
|
||||
declaringClass = findAnnotationDeclaringClass(annotationType, declaringClass.getSuperclass());
|
||||
}
|
||||
|
||||
return attributesList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of the supplied list of {@code ContextConfigurationAttributes}
|
||||
* in reverse order.
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
private static List<ContextConfigurationAttributes> reverseContextConfigurationAttributes(
|
||||
List<ContextConfigurationAttributes> configAttributesList) {
|
||||
List<ContextConfigurationAttributes> configAttributesListReversed = new ArrayList<ContextConfigurationAttributes>(
|
||||
configAttributesList);
|
||||
Collections.reverse(configAttributesListReversed);
|
||||
return configAttributesListReversed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the list of merged {@code ApplicationContextInitializer} classes
|
||||
* for the supplied list of {@code ContextConfigurationAttributes}.
|
||||
*
|
||||
* <p>Note that the {@link ContextConfiguration#inheritInitializers inheritInitializers}
|
||||
* flag of {@link ContextConfiguration @ContextConfiguration} will be taken into
|
||||
* consideration. Specifically, if the <code>inheritInitializers</code> flag is
|
||||
* set to <code>true</code> for a given level in the class hierarchy represented by
|
||||
* the provided configuration attributes, context initializer classes defined
|
||||
* at the given level will be merged with those defined in higher levels
|
||||
* of the class hierarchy.
|
||||
*
|
||||
* @param configAttributesList the list of configuration attributes to process
|
||||
* (must not be <code>null</code>)
|
||||
* @return the list of merged context initializer classes, including those
|
||||
* from superclasses if appropriate (never <code>null</code>)
|
||||
* @since 3.2
|
||||
*/
|
||||
static Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> resolveInitializerClasses(
|
||||
List<ContextConfigurationAttributes> configAttributesList) {
|
||||
Assert.notNull(configAttributesList, "configAttributesList must not be null");
|
||||
|
||||
final Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> initializerClasses = //
|
||||
new HashSet<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>>();
|
||||
|
||||
// Traverse config attributes in reverse order (i.e., as if we were traversing up
|
||||
// the class hierarchy).
|
||||
for (ContextConfigurationAttributes configAttributes : reverseContextConfigurationAttributes(configAttributesList)) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace(String.format("Processing context initializers for context configuration attributes %s",
|
||||
configAttributes));
|
||||
}
|
||||
|
||||
initializerClasses.addAll(Arrays.asList(configAttributes.getInitializers()));
|
||||
|
||||
if (!configAttributes.isInheritInitializers()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return initializerClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve <em>active bean definition profiles</em> for the supplied {@link Class}.
|
||||
*
|
||||
|
@ -266,8 +322,7 @@ abstract class ContextLoaderUtils {
|
|||
ObjectUtils.nullSafeToString(valueProfiles), ObjectUtils.nullSafeToString(profiles));
|
||||
logger.error(msg);
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
else if (!ObjectUtils.isEmpty(valueProfiles)) {
|
||||
} else if (!ObjectUtils.isEmpty(valueProfiles)) {
|
||||
profiles = valueProfiles;
|
||||
}
|
||||
|
||||
|
@ -309,31 +364,38 @@ abstract class ContextLoaderUtils {
|
|||
final List<String> locationsList = new ArrayList<String>();
|
||||
final List<Class<?>> classesList = new ArrayList<Class<?>>();
|
||||
|
||||
for (ContextConfigurationAttributes configAttributes : configAttributesList) {
|
||||
// Traverse config attributes in reverse order (i.e., as if we were traversing up
|
||||
// the class hierarchy).
|
||||
for (ContextConfigurationAttributes configAttributes : reverseContextConfigurationAttributes(configAttributesList)) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace(String.format(
|
||||
"Processing locations and classes for context configuration attributes [%s]", configAttributes));
|
||||
logger.trace(String.format("Processing locations and classes for context configuration attributes %s",
|
||||
configAttributes));
|
||||
}
|
||||
|
||||
if (contextLoader instanceof SmartContextLoader) {
|
||||
SmartContextLoader smartContextLoader = (SmartContextLoader) contextLoader;
|
||||
smartContextLoader.processContextConfiguration(configAttributes);
|
||||
locationsList.addAll(Arrays.asList(configAttributes.getLocations()));
|
||||
classesList.addAll(Arrays.asList(configAttributes.getClasses()));
|
||||
}
|
||||
else {
|
||||
locationsList.addAll(0, Arrays.asList(configAttributes.getLocations()));
|
||||
classesList.addAll(0, Arrays.asList(configAttributes.getClasses()));
|
||||
} else {
|
||||
String[] processedLocations = contextLoader.processLocations(configAttributes.getDeclaringClass(),
|
||||
configAttributes.getLocations());
|
||||
locationsList.addAll(Arrays.asList(processedLocations));
|
||||
locationsList.addAll(0, Arrays.asList(processedLocations));
|
||||
// Legacy ContextLoaders don't know how to process classes
|
||||
}
|
||||
|
||||
if (!configAttributes.isInheritLocations()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
String[] locations = StringUtils.toStringArray(locationsList);
|
||||
Class<?>[] classes = ClassUtils.toClassArray(classesList);
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> initializerClasses = resolveInitializerClasses(configAttributesList);
|
||||
String[] activeProfiles = resolveActiveProfiles(testClass);
|
||||
|
||||
return new MergedContextConfiguration(testClass, locations, classes, activeProfiles, contextLoader);
|
||||
return new MergedContextConfiguration(testClass, locations, classes, initializerClasses, activeProfiles,
|
||||
contextLoader);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,9 +18,13 @@ package org.springframework.test.context;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
@ -59,10 +63,13 @@ public class MergedContextConfiguration implements Serializable {
|
|||
|
||||
private static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
|
||||
private static final Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> EMPTY_INITIALIZER_CLASSES = //
|
||||
Collections.<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> emptySet();
|
||||
|
||||
private final Class<?> testClass;
|
||||
private final String[] locations;
|
||||
private final Class<?>[] classes;
|
||||
private final Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses;
|
||||
private final String[] activeProfiles;
|
||||
private final ContextLoader contextLoader;
|
||||
|
||||
|
@ -75,6 +82,12 @@ public class MergedContextConfiguration implements Serializable {
|
|||
return classes == null ? EMPTY_CLASS_ARRAY : classes;
|
||||
}
|
||||
|
||||
private static Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> processContextInitializerClasses(
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses) {
|
||||
return contextInitializerClasses == null ? EMPTY_INITIALIZER_CLASSES
|
||||
: Collections.unmodifiableSet(contextInitializerClasses);
|
||||
}
|
||||
|
||||
private static String[] processActiveProfiles(String[] activeProfiles) {
|
||||
if (activeProfiles == null) {
|
||||
return EMPTY_STRING_ARRAY;
|
||||
|
@ -111,46 +124,84 @@ public class MergedContextConfiguration implements Serializable {
|
|||
* @param classes the merged annotated classes
|
||||
* @param activeProfiles the merged active bean definition profiles
|
||||
* @param contextLoader the resolved <code>ContextLoader</code>
|
||||
* @see #MergedContextConfiguration(Class, String[], Class[], Set, String[], ContextLoader)
|
||||
*/
|
||||
public MergedContextConfiguration(Class<?> testClass, String[] locations, Class<?>[] classes,
|
||||
String[] activeProfiles, ContextLoader contextLoader) {
|
||||
this(testClass, locations, classes, null, activeProfiles, contextLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code MergedContextConfiguration} instance for the
|
||||
* supplied test class, resource locations, annotated classes, context
|
||||
* initializers, active profiles, and {@code ContextLoader}.
|
||||
*
|
||||
* <p>If a <code>null</code> value is supplied for <code>locations</code>,
|
||||
* <code>classes</code>, or <code>activeProfiles</code> an empty array will
|
||||
* be stored instead. If a <code>null</code> value is supplied for the
|
||||
* <code>contextInitializerClasses</code> 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
|
||||
* @param locations the merged resource locations
|
||||
* @param classes the merged annotated classes
|
||||
* @param contextInitializerClasses the merged context initializer classes
|
||||
* @param activeProfiles the merged active bean definition profiles
|
||||
* @param contextLoader the resolved <code>ContextLoader</code>
|
||||
*/
|
||||
public MergedContextConfiguration(
|
||||
Class<?> testClass,
|
||||
String[] locations,
|
||||
Class<?>[] classes,
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
|
||||
String[] activeProfiles, ContextLoader contextLoader) {
|
||||
this.testClass = testClass;
|
||||
this.locations = processLocations(locations);
|
||||
this.classes = processClasses(classes);
|
||||
this.contextInitializerClasses = processContextInitializerClasses(contextInitializerClasses);
|
||||
this.activeProfiles = processActiveProfiles(activeProfiles);
|
||||
this.contextLoader = contextLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Class test class} associated with this {@code MergedContextConfiguration}.
|
||||
* Get the {@linkplain Class test class} associated with this {@code MergedContextConfiguration}.
|
||||
*/
|
||||
public Class<?> getTestClass() {
|
||||
return testClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the merged resource locations for the {@link #getTestClass() test class}.
|
||||
* Get the merged resource locations for the {@linkplain #getTestClass() test class}.
|
||||
*/
|
||||
public String[] getLocations() {
|
||||
return locations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the merged annotated classes for the {@link #getTestClass() test class}.
|
||||
* Get the merged annotated classes for the {@linkplain #getTestClass() test class}.
|
||||
*/
|
||||
public Class<?>[] getClasses() {
|
||||
return classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the merged active bean definition profiles for the {@link #getTestClass() test class}.
|
||||
* Get the merged {@code ApplicationContextInitializer} classes for the
|
||||
* {@linkplain #getTestClass() test class}.
|
||||
*/
|
||||
public Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> getContextInitializerClasses() {
|
||||
return contextInitializerClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the merged active bean definition profiles for the {@linkplain #getTestClass() test class}.
|
||||
*/
|
||||
public String[] getActiveProfiles() {
|
||||
return activeProfiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resolved {@link ContextLoader} for the {@link #getTestClass() test class}.
|
||||
* Get the resolved {@link ContextLoader} for the {@linkplain #getTestClass() test class}.
|
||||
*/
|
||||
public ContextLoader getContextLoader() {
|
||||
return contextLoader;
|
||||
|
@ -159,7 +210,7 @@ public class MergedContextConfiguration implements Serializable {
|
|||
/**
|
||||
* Generate a unique hash code for all properties of this
|
||||
* {@code MergedContextConfiguration} excluding the
|
||||
* {@link #getTestClass() test class}.
|
||||
* {@linkplain #getTestClass() test class}.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
@ -167,6 +218,7 @@ public class MergedContextConfiguration implements Serializable {
|
|||
int result = 1;
|
||||
result = prime * result + Arrays.hashCode(locations);
|
||||
result = prime * result + Arrays.hashCode(classes);
|
||||
result = prime * result + contextInitializerClasses.hashCode();
|
||||
result = prime * result + Arrays.hashCode(activeProfiles);
|
||||
result = prime * result + nullSafeToString(contextLoader).hashCode();
|
||||
return result;
|
||||
|
@ -174,10 +226,11 @@ public class MergedContextConfiguration implements Serializable {
|
|||
|
||||
/**
|
||||
* Determine if the supplied object is equal to this {@code MergedContextConfiguration}
|
||||
* instance by comparing both object's {@link #getLocations() locations},
|
||||
* {@link #getClasses() annotated classes}, {@link #getActiveProfiles()
|
||||
* active profiles}, and the fully qualified names of their
|
||||
* {@link #getContextLoader() ContextLoaders}.
|
||||
* instance by comparing both object's {@linkplain #getLocations() locations},
|
||||
* {@linkplain #getClasses() annotated classes},
|
||||
* {@linkplain #getContextInitializerClasses() context initializer classes},
|
||||
* {@linkplain #getActiveProfiles() active profiles}, and the fully qualified
|
||||
* names of their {@link #getContextLoader() ContextLoaders}.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
@ -197,6 +250,9 @@ public class MergedContextConfiguration implements Serializable {
|
|||
if (!Arrays.equals(this.classes, that.classes)) {
|
||||
return false;
|
||||
}
|
||||
if (!this.contextInitializerClasses.equals(that.contextInitializerClasses)) {
|
||||
return false;
|
||||
}
|
||||
if (!Arrays.equals(this.activeProfiles, that.activeProfiles)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -208,9 +264,10 @@ public class MergedContextConfiguration implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Provide a String representation of the {@link #getTestClass() test class},
|
||||
* {@link #getLocations() locations}, {@link #getClasses() annotated classes},
|
||||
* {@link #getActiveProfiles() active profiles}, and the name of the
|
||||
* Provide a String representation of the {@linkplain #getTestClass() test class},
|
||||
* {@linkplain #getLocations() locations}, {@linkplain #getClasses() annotated classes},
|
||||
* {@linkplain #getContextInitializerClasses() context initializer classes},
|
||||
* {@linkplain #getActiveProfiles() active profiles}, and the name of the
|
||||
* {@link #getContextLoader() ContextLoader}.
|
||||
*/
|
||||
@Override
|
||||
|
@ -219,6 +276,7 @@ public class MergedContextConfiguration implements Serializable {
|
|||
.append("testClass", testClass)//
|
||||
.append("locations", ObjectUtils.nullSafeToString(locations))//
|
||||
.append("classes", ObjectUtils.nullSafeToString(classes))//
|
||||
.append("contextInitializerClasses", ObjectUtils.nullSafeToString(contextInitializerClasses))//
|
||||
.append("activeProfiles", ObjectUtils.nullSafeToString(activeProfiles))//
|
||||
.append("contextLoader", nullSafeToString(contextLoader))//
|
||||
.toString();
|
||||
|
|
|
@ -16,14 +16,25 @@
|
|||
|
||||
package org.springframework.test.context.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReader;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigUtils;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.test.context.MergedContextConfiguration;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
|
@ -66,11 +77,8 @@ public abstract class AbstractGenericContextLoader extends AbstractContextLoader
|
|||
*
|
||||
* <ul>
|
||||
* <li>Creates a {@link GenericApplicationContext} instance.</li>
|
||||
* <li>Sets the <em>active bean definition profiles</em> from the supplied
|
||||
* <code>MergedContextConfiguration</code> in the
|
||||
* {@link org.springframework.core.env.Environment Environment} of the context.</li>
|
||||
* <li>Calls {@link #prepareContext(GenericApplicationContext)} to allow for customizing the context
|
||||
* before bean definitions are loaded.</li>
|
||||
* <li>Calls {@link #prepareContext(GenericApplicationContext, MergedContextConfiguration)}
|
||||
* to allow for customizing the context before bean definitions are loaded.</li>
|
||||
* <li>Calls {@link #customizeBeanFactory(DefaultListableBeanFactory)} to allow for customizing the
|
||||
* context's <code>DefaultListableBeanFactory</code>.</li>
|
||||
* <li>Delegates to {@link #loadBeanDefinitions(GenericApplicationContext, MergedContextConfiguration)}
|
||||
|
@ -95,9 +103,9 @@ public abstract class AbstractGenericContextLoader extends AbstractContextLoader
|
|||
logger.debug(String.format("Loading ApplicationContext for merged context configuration [%s].",
|
||||
mergedConfig));
|
||||
}
|
||||
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.getEnvironment().setActiveProfiles(mergedConfig.getActiveProfiles());
|
||||
prepareContext(context);
|
||||
prepareContext(context, mergedConfig);
|
||||
customizeBeanFactory(context.getDefaultListableBeanFactory());
|
||||
loadBeanDefinitions(context, mergedConfig);
|
||||
AnnotationConfigUtils.registerAnnotationConfigProcessors(context);
|
||||
|
@ -132,6 +140,7 @@ public abstract class AbstractGenericContextLoader extends AbstractContextLoader
|
|||
*
|
||||
* <p><b>Note</b>: this method does not provide a means to set active bean definition
|
||||
* profiles for the loaded context. See {@link #loadContext(MergedContextConfiguration)}
|
||||
* and {@link #prepareContext(GenericApplicationContext, MergedContextConfiguration)}
|
||||
* for an alternative.
|
||||
*
|
||||
* @return a new application context
|
||||
|
@ -174,6 +183,72 @@ public abstract class AbstractGenericContextLoader extends AbstractContextLoader
|
|||
protected void prepareContext(GenericApplicationContext context) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the {@link GenericApplicationContext} created by this
|
||||
* {@code SmartContextLoader} <i>before</i> bean definitions are read.
|
||||
*
|
||||
* <p>The default implementation:
|
||||
* <ul>
|
||||
* <li>Calls {@link #prepareContext(GenericApplicationContext)} for backwards
|
||||
* compatibility with the {@link org.springframework.test.context.ContextLoader
|
||||
* ContextLoader} SPI.</li>
|
||||
* <li>Sets the <em>active bean definition profiles</em> from the supplied
|
||||
* <code>MergedContextConfiguration</code> in the
|
||||
* {@link org.springframework.core.env.Environment Environment} of the context.</li>
|
||||
* <li>Determines what (if any) context initializer classes have been supplied
|
||||
* via the {@code MergedContextConfiguration} and
|
||||
* {@linkplain ApplicationContextInitializer#initialize invokes each} with the
|
||||
* given application context.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>Any {@code ApplicationContextInitializers} implementing
|
||||
* {@link org.springframework.core.Ordered Ordered} or marked with {@link
|
||||
* org.springframework.core.annotation.Order @Order} will be sorted appropriately.
|
||||
*
|
||||
* @param applicationContext the newly created application context
|
||||
* @param mergedConfig the merged context configuration
|
||||
* @see ApplicationContextInitializer#initialize(GenericApplicationContext)
|
||||
* @see #loadContext(MergedContextConfiguration)
|
||||
* @see GenericApplicationContext#setAllowBeanDefinitionOverriding
|
||||
* @see GenericApplicationContext#setResourceLoader
|
||||
* @see GenericApplicationContext#setId
|
||||
* @since 3.2
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void prepareContext(GenericApplicationContext applicationContext,
|
||||
MergedContextConfiguration mergedConfig) {
|
||||
|
||||
prepareContext(applicationContext);
|
||||
|
||||
applicationContext.getEnvironment().setActiveProfiles(mergedConfig.getActiveProfiles());
|
||||
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> initializerClasses = mergedConfig.getContextInitializerClasses();
|
||||
|
||||
if (initializerClasses.size() == 0) {
|
||||
// no ApplicationContextInitializers have been declared -> nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
final List<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerInstances = new ArrayList<ApplicationContextInitializer<ConfigurableApplicationContext>>();
|
||||
final Class<?> contextClass = applicationContext.getClass();
|
||||
|
||||
for (Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>> initializerClass : initializerClasses) {
|
||||
Class<?> initializerContextClass = GenericTypeResolver.resolveTypeArgument(initializerClass,
|
||||
ApplicationContextInitializer.class);
|
||||
Assert.isAssignable(initializerContextClass, contextClass, String.format(
|
||||
"Could not add context initializer [%s] since its generic parameter [%s] "
|
||||
+ "is not assignable from the type of application context used by this "
|
||||
+ "context loader [%s]: ", initializerClass.getName(), initializerContextClass.getName(),
|
||||
contextClass.getName()));
|
||||
initializerInstances.add((ApplicationContextInitializer<ConfigurableApplicationContext>) BeanUtils.instantiateClass(initializerClass));
|
||||
}
|
||||
|
||||
Collections.sort(initializerInstances, new AnnotationAwareOrderComparator());
|
||||
for (ApplicationContextInitializer<ConfigurableApplicationContext> initializer : initializerInstances) {
|
||||
initializer.initialize(applicationContext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize the internal bean factory of the ApplicationContext created by
|
||||
* this <code>ContextLoader</code>.
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.util.List;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.ContextConfigurationAttributes;
|
||||
|
@ -50,6 +51,12 @@ import org.springframework.util.ObjectUtils;
|
|||
* the default loader, thus providing automatic support for either XML configuration
|
||||
* files or annotated classes, but not both simultaneously.
|
||||
*
|
||||
* <p>As of Spring 3.2, a test class may optionally declare neither XML configuration
|
||||
* files nor annotated classes and instead declare only {@linkplain
|
||||
* ContextConfiguration#initializers application context initializers}. In such
|
||||
* cases, an attempt will still be made to detect defaults, but their absence will
|
||||
* not result an an exception.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 3.1
|
||||
* @see SmartContextLoader
|
||||
|
@ -78,11 +85,18 @@ public class DelegatingSmartContextLoader implements SmartContextLoader {
|
|||
loader.processContextConfiguration(configAttributes);
|
||||
}
|
||||
|
||||
private static ApplicationContext delegateLoading(SmartContextLoader loader, MergedContextConfiguration mergedConfig)
|
||||
throws Exception {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("Delegating to %s to load context from %s.", name(loader), mergedConfig));
|
||||
}
|
||||
return loader.loadContext(mergedConfig);
|
||||
}
|
||||
|
||||
private static boolean supports(SmartContextLoader loader, MergedContextConfiguration mergedConfig) {
|
||||
if (loader instanceof AnnotationConfigContextLoader) {
|
||||
return ObjectUtils.isEmpty(mergedConfig.getLocations()) && !ObjectUtils.isEmpty(mergedConfig.getClasses());
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return !ObjectUtils.isEmpty(mergedConfig.getLocations()) && ObjectUtils.isEmpty(mergedConfig.getClasses());
|
||||
}
|
||||
}
|
||||
|
@ -132,11 +146,9 @@ public class DelegatingSmartContextLoader implements SmartContextLoader {
|
|||
// appropriate loader process the configuration.
|
||||
if (configAttributes.hasLocations()) {
|
||||
delegateProcessing(xmlLoader, configAttributes);
|
||||
}
|
||||
else if (configAttributes.hasClasses()) {
|
||||
} else if (configAttributes.hasClasses()) {
|
||||
delegateProcessing(annotationConfigLoader, configAttributes);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Else attempt to detect defaults...
|
||||
|
||||
// Let the XML loader process the configuration.
|
||||
|
@ -173,10 +185,12 @@ public class DelegatingSmartContextLoader implements SmartContextLoader {
|
|||
name(annotationConfigLoader), configAttributes));
|
||||
}
|
||||
|
||||
// If neither loader detected defaults, throw an exception.
|
||||
if (!configAttributes.hasResources()) {
|
||||
// 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 for context configuration %s.", name(xmlLoader),
|
||||
"Neither %s nor %s was able to detect defaults, and no ApplicationContextInitializers "
|
||||
+ "were declared for context configuration %s", name(xmlLoader),
|
||||
name(annotationConfigLoader), configAttributes));
|
||||
}
|
||||
|
||||
|
@ -219,16 +233,19 @@ public class DelegatingSmartContextLoader implements SmartContextLoader {
|
|||
List<SmartContextLoader> candidates = Arrays.asList(xmlLoader, annotationConfigLoader);
|
||||
|
||||
for (SmartContextLoader loader : candidates) {
|
||||
// Determine if each loader can load a context from the
|
||||
// mergedConfig. If it can, let it; otherwise, keep iterating.
|
||||
// Determine if each loader can load a context from the mergedConfig. If it
|
||||
// can, let it; otherwise, keep iterating.
|
||||
if (supports(loader, mergedConfig)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("Delegating to %s to load context from %s.", name(loader), mergedConfig));
|
||||
}
|
||||
return loader.loadContext(mergedConfig);
|
||||
return delegateLoading(loader, mergedConfig);
|
||||
}
|
||||
}
|
||||
|
||||
// If neither of the candidates supports the mergedConfig based on resources but
|
||||
// ACIs were declared, then delegate to the ACCL.
|
||||
if (!mergedConfig.getContextInitializerClasses().isEmpty()) {
|
||||
return delegateLoading(annotationConfigLoader, mergedConfig);
|
||||
}
|
||||
|
||||
throw new IllegalStateException(String.format(
|
||||
"Neither %s nor %s was able to load an ApplicationContext from %s.", name(xmlLoader),
|
||||
name(annotationConfigLoader), mergedConfig));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* 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.
|
||||
|
@ -16,19 +16,24 @@
|
|||
|
||||
package org.springframework.test.context;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.test.context.ContextLoaderUtils.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
import org.springframework.test.context.support.DelegatingSmartContextLoader;
|
||||
import org.springframework.test.context.support.GenericPropertiesContextLoader;
|
||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ContextLoaderUtils}.
|
||||
|
@ -40,6 +45,8 @@ public class ContextLoaderUtilsTests {
|
|||
|
||||
private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
|
||||
private static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
private static final Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> EMPTY_INITIALIZER_CLASSES = //
|
||||
Collections.<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> emptySet();
|
||||
|
||||
|
||||
private void assertAttributes(ContextConfigurationAttributes attributes, Class<?> expectedDeclaringClass,
|
||||
|
@ -72,9 +79,20 @@ public class ContextLoaderUtilsTests {
|
|||
AnnotationConfigContextLoader.class, true);
|
||||
}
|
||||
|
||||
private void assertMergedContextConfiguration(MergedContextConfiguration mergedConfig, Class<?> expectedTestClass,
|
||||
private void assertMergedConfig(MergedContextConfiguration mergedConfig, Class<?> expectedTestClass,
|
||||
String[] expectedLocations, Class<?>[] expectedClasses,
|
||||
Class<? extends ContextLoader> expectedContextLoaderClass) {
|
||||
assertMergedConfig(mergedConfig, expectedTestClass, expectedLocations, expectedClasses,
|
||||
EMPTY_INITIALIZER_CLASSES, expectedContextLoaderClass);
|
||||
}
|
||||
|
||||
private void assertMergedConfig(
|
||||
MergedContextConfiguration mergedConfig,
|
||||
Class<?> expectedTestClass,
|
||||
String[] expectedLocations,
|
||||
Class<?>[] expectedClasses,
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> expectedInitializerClasses,
|
||||
Class<? extends ContextLoader> expectedContextLoaderClass) {
|
||||
assertNotNull(mergedConfig);
|
||||
assertEquals(expectedTestClass, mergedConfig.getTestClass());
|
||||
assertNotNull(mergedConfig.getLocations());
|
||||
|
@ -83,16 +101,18 @@ public class ContextLoaderUtilsTests {
|
|||
assertArrayEquals(expectedClasses, mergedConfig.getClasses());
|
||||
assertNotNull(mergedConfig.getActiveProfiles());
|
||||
assertEquals(expectedContextLoaderClass, mergedConfig.getContextLoader().getClass());
|
||||
assertNotNull(mergedConfig.getContextInitializerClasses());
|
||||
assertEquals(expectedInitializerClasses, mergedConfig.getContextInitializerClasses());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void resolveContextConfigurationAttributesWithConflictingLocations() {
|
||||
ContextLoaderUtils.resolveContextConfigurationAttributes(ConflictingLocations.class);
|
||||
public void resolveConfigAttributesWithConflictingLocations() {
|
||||
resolveContextConfigurationAttributes(ConflictingLocations.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveContextConfigurationAttributesWithBareAnnotations() {
|
||||
List<ContextConfigurationAttributes> attributesList = ContextLoaderUtils.resolveContextConfigurationAttributes(BareAnnotations.class);
|
||||
public void resolveConfigAttributesWithBareAnnotations() {
|
||||
List<ContextConfigurationAttributes> attributesList = resolveContextConfigurationAttributes(BareAnnotations.class);
|
||||
assertNotNull(attributesList);
|
||||
assertEquals(1, attributesList.size());
|
||||
assertAttributes(attributesList.get(0), BareAnnotations.class, EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY,
|
||||
|
@ -100,24 +120,24 @@ public class ContextLoaderUtilsTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void resolveContextConfigurationAttributesWithLocalAnnotationAndLocations() {
|
||||
List<ContextConfigurationAttributes> attributesList = ContextLoaderUtils.resolveContextConfigurationAttributes(LocationsFoo.class);
|
||||
public void resolveConfigAttributesWithLocalAnnotationAndLocations() {
|
||||
List<ContextConfigurationAttributes> attributesList = resolveContextConfigurationAttributes(LocationsFoo.class);
|
||||
assertNotNull(attributesList);
|
||||
assertEquals(1, attributesList.size());
|
||||
assertLocationsFooAttributes(attributesList.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveContextConfigurationAttributesWithLocalAnnotationAndClasses() {
|
||||
List<ContextConfigurationAttributes> attributesList = ContextLoaderUtils.resolveContextConfigurationAttributes(ClassesFoo.class);
|
||||
public void resolveConfigAttributesWithLocalAnnotationAndClasses() {
|
||||
List<ContextConfigurationAttributes> attributesList = resolveContextConfigurationAttributes(ClassesFoo.class);
|
||||
assertNotNull(attributesList);
|
||||
assertEquals(1, attributesList.size());
|
||||
assertClassesFooAttributes(attributesList.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveContextConfigurationAttributesWithLocalAndInheritedAnnotationsAndLocations() {
|
||||
List<ContextConfigurationAttributes> attributesList = ContextLoaderUtils.resolveContextConfigurationAttributes(LocationsBar.class);
|
||||
public void resolveConfigAttributesWithLocalAndInheritedAnnotationsAndLocations() {
|
||||
List<ContextConfigurationAttributes> attributesList = resolveContextConfigurationAttributes(LocationsBar.class);
|
||||
assertNotNull(attributesList);
|
||||
assertEquals(2, attributesList.size());
|
||||
assertLocationsFooAttributes(attributesList.get(0));
|
||||
|
@ -125,8 +145,8 @@ public class ContextLoaderUtilsTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void resolveContextConfigurationAttributesWithLocalAndInheritedAnnotationsAndClasses() {
|
||||
List<ContextConfigurationAttributes> attributesList = ContextLoaderUtils.resolveContextConfigurationAttributes(ClassesBar.class);
|
||||
public void resolveConfigAttributesWithLocalAndInheritedAnnotationsAndClasses() {
|
||||
List<ContextConfigurationAttributes> attributesList = resolveContextConfigurationAttributes(ClassesBar.class);
|
||||
assertNotNull(attributesList);
|
||||
assertEquals(2, attributesList.size());
|
||||
assertClassesFooAttributes(attributesList.get(0));
|
||||
|
@ -134,16 +154,16 @@ public class ContextLoaderUtilsTests {
|
|||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void buildMergedContextConfigurationWithoutAnnotation() {
|
||||
ContextLoaderUtils.buildMergedContextConfiguration(Enigma.class, null);
|
||||
public void buildMergedConfigWithoutAnnotation() {
|
||||
buildMergedContextConfiguration(Enigma.class, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildMergedContextConfigurationWithBareAnnotations() {
|
||||
public void buildMergedConfigWithBareAnnotations() {
|
||||
Class<BareAnnotations> testClass = BareAnnotations.class;
|
||||
MergedContextConfiguration mergedConfig = ContextLoaderUtils.buildMergedContextConfiguration(testClass, null);
|
||||
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass, null);
|
||||
|
||||
assertMergedContextConfiguration(
|
||||
assertMergedConfig(
|
||||
mergedConfig,
|
||||
testClass,
|
||||
new String[] { "classpath:/org/springframework/test/context/ContextLoaderUtilsTests$BareAnnotations-context.xml" },
|
||||
|
@ -151,86 +171,159 @@ public class ContextLoaderUtilsTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void buildMergedContextConfigurationWithLocalAnnotationAndLocations() {
|
||||
public void buildMergedConfigWithLocalAnnotationAndLocations() {
|
||||
Class<?> testClass = LocationsFoo.class;
|
||||
MergedContextConfiguration mergedConfig = ContextLoaderUtils.buildMergedContextConfiguration(testClass, null);
|
||||
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass, null);
|
||||
|
||||
assertMergedContextConfiguration(mergedConfig, testClass, new String[] { "classpath:/foo.xml" },
|
||||
EMPTY_CLASS_ARRAY, DelegatingSmartContextLoader.class);
|
||||
assertMergedConfig(mergedConfig, testClass, new String[] { "classpath:/foo.xml" }, EMPTY_CLASS_ARRAY,
|
||||
DelegatingSmartContextLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildMergedContextConfigurationWithLocalAnnotationAndClasses() {
|
||||
public void buildMergedConfigWithLocalAnnotationAndClasses() {
|
||||
Class<?> testClass = ClassesFoo.class;
|
||||
MergedContextConfiguration mergedConfig = ContextLoaderUtils.buildMergedContextConfiguration(testClass, null);
|
||||
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass, null);
|
||||
|
||||
assertMergedContextConfiguration(mergedConfig, testClass, EMPTY_STRING_ARRAY,
|
||||
new Class<?>[] { FooConfig.class }, DelegatingSmartContextLoader.class);
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, new Class<?>[] { FooConfig.class },
|
||||
DelegatingSmartContextLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildMergedContextConfigurationWithLocalAnnotationAndOverriddenContextLoaderAndLocations() {
|
||||
public void buildMergedConfigWithLocalAnnotationAndOverriddenContextLoaderAndLocations() {
|
||||
Class<?> testClass = LocationsFoo.class;
|
||||
Class<? extends ContextLoader> expectedContextLoaderClass = GenericPropertiesContextLoader.class;
|
||||
MergedContextConfiguration mergedConfig = ContextLoaderUtils.buildMergedContextConfiguration(testClass,
|
||||
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass,
|
||||
expectedContextLoaderClass.getName());
|
||||
|
||||
assertMergedContextConfiguration(mergedConfig, testClass, new String[] { "classpath:/foo.xml" },
|
||||
EMPTY_CLASS_ARRAY, expectedContextLoaderClass);
|
||||
assertMergedConfig(mergedConfig, testClass, new String[] { "classpath:/foo.xml" }, EMPTY_CLASS_ARRAY,
|
||||
expectedContextLoaderClass);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildMergedContextConfigurationWithLocalAnnotationAndOverriddenContextLoaderAndClasses() {
|
||||
public void buildMergedConfigWithLocalAnnotationAndOverriddenContextLoaderAndClasses() {
|
||||
Class<?> testClass = ClassesFoo.class;
|
||||
Class<? extends ContextLoader> expectedContextLoaderClass = GenericPropertiesContextLoader.class;
|
||||
MergedContextConfiguration mergedConfig = ContextLoaderUtils.buildMergedContextConfiguration(testClass,
|
||||
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass,
|
||||
expectedContextLoaderClass.getName());
|
||||
|
||||
assertMergedContextConfiguration(mergedConfig, testClass, EMPTY_STRING_ARRAY,
|
||||
new Class<?>[] { FooConfig.class }, expectedContextLoaderClass);
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, new Class<?>[] { FooConfig.class },
|
||||
expectedContextLoaderClass);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildMergedContextConfigurationWithLocalAndInheritedAnnotationsAndLocations() {
|
||||
public void buildMergedConfigWithLocalAndInheritedAnnotationsAndLocations() {
|
||||
Class<?> testClass = LocationsBar.class;
|
||||
String[] expectedLocations = new String[] { "/foo.xml", "/bar.xml" };
|
||||
|
||||
MergedContextConfiguration mergedConfig = ContextLoaderUtils.buildMergedContextConfiguration(testClass, null);
|
||||
assertMergedContextConfiguration(mergedConfig, testClass, expectedLocations, EMPTY_CLASS_ARRAY,
|
||||
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass, null);
|
||||
assertMergedConfig(mergedConfig, testClass, expectedLocations, EMPTY_CLASS_ARRAY,
|
||||
AnnotationConfigContextLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildMergedContextConfigurationWithLocalAndInheritedAnnotationsAndClasses() {
|
||||
public void buildMergedConfigWithLocalAndInheritedAnnotationsAndClasses() {
|
||||
Class<?> testClass = ClassesBar.class;
|
||||
Class<?>[] expectedClasses = new Class<?>[] { FooConfig.class, BarConfig.class };
|
||||
|
||||
MergedContextConfiguration mergedConfig = ContextLoaderUtils.buildMergedContextConfiguration(testClass, null);
|
||||
assertMergedContextConfiguration(mergedConfig, testClass, EMPTY_STRING_ARRAY, expectedClasses,
|
||||
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass, null);
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, expectedClasses,
|
||||
AnnotationConfigContextLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildMergedConfigWithAnnotationsAndOverriddenLocations() {
|
||||
Class<?> testClass = OverriddenLocationsBar.class;
|
||||
String[] expectedLocations = new String[] { "/bar.xml" };
|
||||
|
||||
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass, null);
|
||||
assertMergedConfig(mergedConfig, testClass, expectedLocations, EMPTY_CLASS_ARRAY,
|
||||
AnnotationConfigContextLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildMergedConfigWithAnnotationsAndOverriddenClasses() {
|
||||
Class<?> testClass = OverriddenClassesBar.class;
|
||||
Class<?>[] expectedClasses = new Class<?>[] { BarConfig.class };
|
||||
|
||||
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass, null);
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, expectedClasses,
|
||||
AnnotationConfigContextLoader.class);
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass, null);
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, expectedClasses, expectedInitializerClasses,
|
||||
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, null);
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, expectedClasses, expectedInitializerClasses,
|
||||
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, null);
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, expectedClasses, expectedInitializerClasses,
|
||||
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, null);
|
||||
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, expectedClasses, expectedInitializerClasses,
|
||||
DelegatingSmartContextLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveActiveProfilesWithoutAnnotation() {
|
||||
String[] profiles = ContextLoaderUtils.resolveActiveProfiles(Enigma.class);
|
||||
String[] profiles = resolveActiveProfiles(Enigma.class);
|
||||
assertArrayEquals(EMPTY_STRING_ARRAY, profiles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveActiveProfilesWithNoProfilesDeclared() {
|
||||
String[] profiles = ContextLoaderUtils.resolveActiveProfiles(BareAnnotations.class);
|
||||
String[] profiles = resolveActiveProfiles(BareAnnotations.class);
|
||||
assertArrayEquals(EMPTY_STRING_ARRAY, profiles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveActiveProfilesWithEmptyProfiles() {
|
||||
String[] profiles = ContextLoaderUtils.resolveActiveProfiles(EmptyProfiles.class);
|
||||
String[] profiles = resolveActiveProfiles(EmptyProfiles.class);
|
||||
assertArrayEquals(EMPTY_STRING_ARRAY, profiles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveActiveProfilesWithDuplicatedProfiles() {
|
||||
String[] profiles = ContextLoaderUtils.resolveActiveProfiles(DuplicatedProfiles.class);
|
||||
String[] profiles = resolveActiveProfiles(DuplicatedProfiles.class);
|
||||
assertNotNull(profiles);
|
||||
assertEquals(3, profiles.length);
|
||||
|
||||
|
@ -242,28 +335,28 @@ public class ContextLoaderUtilsTests {
|
|||
|
||||
@Test
|
||||
public void resolveActiveProfilesWithLocalAnnotation() {
|
||||
String[] profiles = ContextLoaderUtils.resolveActiveProfiles(LocationsFoo.class);
|
||||
String[] profiles = resolveActiveProfiles(LocationsFoo.class);
|
||||
assertNotNull(profiles);
|
||||
assertArrayEquals(new String[] { "foo" }, profiles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveActiveProfilesWithInheritedAnnotationAndLocations() {
|
||||
String[] profiles = ContextLoaderUtils.resolveActiveProfiles(InheritedLocationsFoo.class);
|
||||
String[] profiles = resolveActiveProfiles(InheritedLocationsFoo.class);
|
||||
assertNotNull(profiles);
|
||||
assertArrayEquals(new String[] { "foo" }, profiles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveActiveProfilesWithInheritedAnnotationAndClasses() {
|
||||
String[] profiles = ContextLoaderUtils.resolveActiveProfiles(InheritedClassesFoo.class);
|
||||
String[] profiles = resolveActiveProfiles(InheritedClassesFoo.class);
|
||||
assertNotNull(profiles);
|
||||
assertArrayEquals(new String[] { "foo" }, profiles);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveActiveProfilesWithLocalAndInheritedAnnotations() {
|
||||
String[] profiles = ContextLoaderUtils.resolveActiveProfiles(LocationsBar.class);
|
||||
String[] profiles = resolveActiveProfiles(LocationsBar.class);
|
||||
assertNotNull(profiles);
|
||||
assertEquals(2, profiles.length);
|
||||
|
||||
|
@ -274,7 +367,7 @@ public class ContextLoaderUtilsTests {
|
|||
|
||||
@Test
|
||||
public void resolveActiveProfilesWithOverriddenAnnotation() {
|
||||
String[] profiles = ContextLoaderUtils.resolveActiveProfiles(Animals.class);
|
||||
String[] profiles = resolveActiveProfiles(Animals.class);
|
||||
assertNotNull(profiles);
|
||||
assertEquals(2, profiles.length);
|
||||
|
||||
|
@ -333,13 +426,51 @@ public class ContextLoaderUtilsTests {
|
|||
private static class LocationsBar extends LocationsFoo {
|
||||
}
|
||||
|
||||
@ContextConfiguration(locations = "/bar.xml", inheritLocations = false, loader = AnnotationConfigContextLoader.class)
|
||||
@ActiveProfiles("bar")
|
||||
private static class OverriddenLocationsBar extends LocationsFoo {
|
||||
}
|
||||
|
||||
@ContextConfiguration(classes = BarConfig.class, inheritLocations = true, loader = AnnotationConfigContextLoader.class)
|
||||
@ActiveProfiles("bar")
|
||||
private static class ClassesBar extends ClassesFoo {
|
||||
}
|
||||
|
||||
@ContextConfiguration(classes = BarConfig.class, inheritLocations = false, loader = AnnotationConfigContextLoader.class)
|
||||
@ActiveProfiles("bar")
|
||||
private static class OverriddenClassesBar extends ClassesFoo {
|
||||
}
|
||||
|
||||
@ActiveProfiles(profiles = { "dog", "cat" }, inheritProfiles = false)
|
||||
private static class Animals extends LocationsBar {
|
||||
}
|
||||
|
||||
private static class FooInitializer implements ApplicationContextInitializer<GenericApplicationContext> {
|
||||
|
||||
public void initialize(GenericApplicationContext applicationContext) {
|
||||
}
|
||||
}
|
||||
|
||||
private static class BarInitializer implements ApplicationContextInitializer<GenericWebApplicationContext> {
|
||||
|
||||
public void initialize(GenericWebApplicationContext applicationContext) {
|
||||
}
|
||||
}
|
||||
|
||||
@ContextConfiguration(classes = FooConfig.class, initializers = FooInitializer.class)
|
||||
private static class InitializersFoo {
|
||||
}
|
||||
|
||||
@ContextConfiguration(classes = BarConfig.class, initializers = BarInitializer.class)
|
||||
private static class InitializersBar extends InitializersFoo {
|
||||
}
|
||||
|
||||
@ContextConfiguration(classes = BarConfig.class, initializers = BarInitializer.class, inheritInitializers = false)
|
||||
private static class OverriddenInitializersBar extends InitializersFoo {
|
||||
}
|
||||
|
||||
@ContextConfiguration(classes = BarConfig.class, inheritLocations = false, initializers = BarInitializer.class, inheritInitializers = false)
|
||||
private static class OverriddenInitializersAndClassesBar extends InitializersFoo {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* 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.
|
||||
|
@ -16,17 +16,25 @@
|
|||
|
||||
package org.springframework.test.context;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
import org.springframework.test.context.support.GenericXmlContextLoader;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MergedContextConfiguration}.
|
||||
*
|
||||
* <p>These tests primarily exist to ensure that {@code MergedContextConfiguration}
|
||||
* can safely be used as the cache key for {@link ContextCache}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 3.1
|
||||
*/
|
||||
|
@ -42,6 +50,7 @@ public class MergedContextConfigurationTests {
|
|||
public void hashCodeWithNulls() {
|
||||
MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(null, null, null, null, null);
|
||||
MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(null, null, null, null, null);
|
||||
assertTrue(mergedConfig1.hashCode() > 0);
|
||||
assertEquals(mergedConfig1.hashCode(), mergedConfig2.hashCode());
|
||||
}
|
||||
|
||||
|
@ -155,6 +164,42 @@ public class MergedContextConfigurationTests {
|
|||
assertFalse(mergedConfig1.hashCode() == mergedConfig2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hashCodeWithSameInitializers() {
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> initializerClasses1 = //
|
||||
new HashSet<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>>();
|
||||
initializerClasses1.add(FooInitializer.class);
|
||||
initializerClasses1.add(BarInitializer.class);
|
||||
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> initializerClasses2 = //
|
||||
new HashSet<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>>();
|
||||
initializerClasses2.add(BarInitializer.class);
|
||||
initializerClasses2.add(FooInitializer.class);
|
||||
|
||||
MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY,
|
||||
EMPTY_CLASS_ARRAY, initializerClasses1, EMPTY_STRING_ARRAY, loader);
|
||||
MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY,
|
||||
EMPTY_CLASS_ARRAY, initializerClasses2, EMPTY_STRING_ARRAY, loader);
|
||||
assertEquals(mergedConfig1.hashCode(), mergedConfig2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hashCodeWithDifferentInitializers() {
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> initializerClasses1 = //
|
||||
new HashSet<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>>();
|
||||
initializerClasses1.add(FooInitializer.class);
|
||||
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> initializerClasses2 = //
|
||||
new HashSet<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>>();
|
||||
initializerClasses2.add(BarInitializer.class);
|
||||
|
||||
MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY,
|
||||
EMPTY_CLASS_ARRAY, initializerClasses1, EMPTY_STRING_ARRAY, loader);
|
||||
MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY,
|
||||
EMPTY_CLASS_ARRAY, initializerClasses2, EMPTY_STRING_ARRAY, loader);
|
||||
assertFalse(mergedConfig1.hashCode() == mergedConfig2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalsBasics() {
|
||||
MergedContextConfiguration mergedConfig = new MergedContextConfiguration(null, null, null, null, null);
|
||||
|
@ -193,6 +238,7 @@ public class MergedContextConfigurationTests {
|
|||
MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY,
|
||||
EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, new AnnotationConfigContextLoader());
|
||||
assertFalse(mergedConfig1.equals(mergedConfig2));
|
||||
assertFalse(mergedConfig2.equals(mergedConfig1));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -214,6 +260,7 @@ public class MergedContextConfigurationTests {
|
|||
MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), locations2,
|
||||
EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader);
|
||||
assertFalse(mergedConfig1.equals(mergedConfig2));
|
||||
assertFalse(mergedConfig2.equals(mergedConfig1));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -235,6 +282,7 @@ public class MergedContextConfigurationTests {
|
|||
MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY,
|
||||
classes2, EMPTY_STRING_ARRAY, loader);
|
||||
assertFalse(mergedConfig1.equals(mergedConfig2));
|
||||
assertFalse(mergedConfig2.equals(mergedConfig1));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -278,6 +326,57 @@ public class MergedContextConfigurationTests {
|
|||
MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY,
|
||||
EMPTY_CLASS_ARRAY, activeProfiles2, loader);
|
||||
assertFalse(mergedConfig1.equals(mergedConfig2));
|
||||
assertFalse(mergedConfig2.equals(mergedConfig1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalsWithSameInitializers() {
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> initializerClasses1 = //
|
||||
new HashSet<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>>();
|
||||
initializerClasses1.add(FooInitializer.class);
|
||||
initializerClasses1.add(BarInitializer.class);
|
||||
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> initializerClasses2 = //
|
||||
new HashSet<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>>();
|
||||
initializerClasses2.add(BarInitializer.class);
|
||||
initializerClasses2.add(FooInitializer.class);
|
||||
|
||||
MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY,
|
||||
EMPTY_CLASS_ARRAY, initializerClasses1, EMPTY_STRING_ARRAY, loader);
|
||||
MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY,
|
||||
EMPTY_CLASS_ARRAY, initializerClasses2, EMPTY_STRING_ARRAY, loader);
|
||||
assertEquals(mergedConfig1, mergedConfig2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalsWithDifferentInitializers() {
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> initializerClasses1 = //
|
||||
new HashSet<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>>();
|
||||
initializerClasses1.add(FooInitializer.class);
|
||||
|
||||
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> initializerClasses2 = //
|
||||
new HashSet<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>>();
|
||||
initializerClasses2.add(BarInitializer.class);
|
||||
|
||||
MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY,
|
||||
EMPTY_CLASS_ARRAY, initializerClasses1, EMPTY_STRING_ARRAY, loader);
|
||||
MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY,
|
||||
EMPTY_CLASS_ARRAY, initializerClasses2, EMPTY_STRING_ARRAY, loader);
|
||||
assertFalse(mergedConfig1.equals(mergedConfig2));
|
||||
assertFalse(mergedConfig2.equals(mergedConfig1));
|
||||
}
|
||||
|
||||
|
||||
private static class FooInitializer implements ApplicationContextInitializer<GenericApplicationContext> {
|
||||
|
||||
public void initialize(GenericApplicationContext applicationContext) {
|
||||
}
|
||||
}
|
||||
|
||||
private static class BarInitializer implements ApplicationContextInitializer<GenericApplicationContext> {
|
||||
|
||||
public void initialize(GenericApplicationContext applicationContext) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.aci;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.test.context.junit4.aci.annotation.InitializerWithoutConfigFilesOrClassesTest;
|
||||
import org.springframework.test.context.junit4.aci.annotation.MergedInitializersAnnotationConfigTests;
|
||||
import org.springframework.test.context.junit4.aci.annotation.MultipleInitializersAnnotationConfigTests;
|
||||
import org.springframework.test.context.junit4.aci.annotation.OrderedInitializersAnnotationConfigTests;
|
||||
import org.springframework.test.context.junit4.aci.annotation.OverriddenInitializersAnnotationConfigTests;
|
||||
import org.springframework.test.context.junit4.aci.annotation.SingleInitializerAnnotationConfigTests;
|
||||
import org.springframework.test.context.junit4.aci.xml.MultipleInitializersXmlConfigTests;
|
||||
|
||||
/**
|
||||
* Convenience test suite for integration tests that verify support for
|
||||
* {@link ApplicationContextInitializer ApplicationContextInitializers} (ACIs)
|
||||
* in the TestContext framework.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
*/
|
||||
@RunWith(Suite.class)
|
||||
// Note: the following 'multi-line' layout is for enhanced code readability.
|
||||
@SuiteClasses({//
|
||||
MultipleInitializersXmlConfigTests.class,//
|
||||
SingleInitializerAnnotationConfigTests.class,//
|
||||
MultipleInitializersAnnotationConfigTests.class,//
|
||||
MergedInitializersAnnotationConfigTests.class,//
|
||||
OverriddenInitializersAnnotationConfigTests.class,//
|
||||
OrderedInitializersAnnotationConfigTests.class,//
|
||||
InitializerWithoutConfigFilesOrClassesTest.class //
|
||||
})
|
||||
public class AciTestSuite {
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.aci;
|
||||
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
*/
|
||||
public class DevProfileInitializer implements ApplicationContextInitializer<GenericApplicationContext> {
|
||||
|
||||
public void initialize(GenericApplicationContext applicationContext) {
|
||||
applicationContext.getEnvironment().setActiveProfiles("dev");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.aci;
|
||||
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
*/
|
||||
public class FooBarAliasInitializer implements ApplicationContextInitializer<GenericApplicationContext> {
|
||||
|
||||
public void initialize(GenericApplicationContext applicationContext) {
|
||||
applicationContext.registerAlias("foo", "bar");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.aci.annotation;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
|
||||
/**
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
*/
|
||||
@Configuration
|
||||
@Profile("dev")
|
||||
class DevProfileConfig {
|
||||
|
||||
@Bean
|
||||
public String baz() {
|
||||
return "dev profile config";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.aci.annotation;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
*/
|
||||
@Configuration
|
||||
class GlobalConfig {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
@Bean
|
||||
public String baz() {
|
||||
return "global config";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.aci.annotation;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit4.aci.annotation.InitializerWithoutConfigFilesOrClassesTest.EntireAppInitializer;
|
||||
|
||||
/**
|
||||
* Integration test that verifies support for {@link ApplicationContextInitializer
|
||||
* ApplicationContextInitializers} in the TestContext framework when the test
|
||||
* class declares neither XML configuration files nor annotated configuration classes.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(initializers = EntireAppInitializer.class)
|
||||
public class InitializerWithoutConfigFilesOrClassesTest {
|
||||
|
||||
@Autowired
|
||||
private String foo;
|
||||
|
||||
|
||||
@Test
|
||||
public void foo() {
|
||||
assertEquals("foo", foo);
|
||||
}
|
||||
|
||||
|
||||
static class EntireAppInitializer implements ApplicationContextInitializer<GenericApplicationContext> {
|
||||
|
||||
public void initialize(GenericApplicationContext applicationContext) {
|
||||
new AnnotatedBeanDefinitionReader(applicationContext).register(GlobalConfig.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
*
|
||||
* 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.aci.annotation;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.aci.DevProfileInitializer;
|
||||
|
||||
/**
|
||||
* Integration tests that verify support for {@link ApplicationContextInitializer
|
||||
* ApplicationContextInitializers} in conjunction with annotation-driven
|
||||
* configuration in the TestContext framework.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
*/
|
||||
@ContextConfiguration(initializers = DevProfileInitializer.class)
|
||||
public class MergedInitializersAnnotationConfigTests extends SingleInitializerAnnotationConfigTests {
|
||||
|
||||
@Test
|
||||
public void activeBeans() {
|
||||
assertEquals("foo", foo);
|
||||
assertEquals("foo", bar);
|
||||
assertEquals("dev profile config", baz);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.aci.annotation;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit4.aci.DevProfileInitializer;
|
||||
import org.springframework.test.context.junit4.aci.FooBarAliasInitializer;
|
||||
|
||||
/**
|
||||
* Integration tests that verify support for {@link ApplicationContextInitializer
|
||||
* ApplicationContextInitializers} in conjunction with annotation-driven
|
||||
* configuration in the TestContext framework.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { GlobalConfig.class, DevProfileConfig.class }, initializers = {
|
||||
FooBarAliasInitializer.class, DevProfileInitializer.class })
|
||||
public class MultipleInitializersAnnotationConfigTests {
|
||||
|
||||
@Autowired
|
||||
private String foo, bar, baz;
|
||||
|
||||
|
||||
@Test
|
||||
public void activeBeans() {
|
||||
assertEquals("foo", foo);
|
||||
assertEquals("foo", bar);
|
||||
assertEquals("dev profile config", baz);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.aci.annotation;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit4.aci.annotation.OrderedInitializersAnnotationConfigTests.ConfigTwo;
|
||||
import org.springframework.test.context.junit4.aci.annotation.OrderedInitializersAnnotationConfigTests.ConfigOne;
|
||||
import org.springframework.test.context.junit4.aci.annotation.OrderedInitializersAnnotationConfigTests.GlobalConfig;
|
||||
import org.springframework.test.context.junit4.aci.annotation.OrderedInitializersAnnotationConfigTests.OrderedOneInitializer;
|
||||
import org.springframework.test.context.junit4.aci.annotation.OrderedInitializersAnnotationConfigTests.OrderedTwoInitializer;
|
||||
|
||||
/**
|
||||
* Integration tests that verify that any {@link ApplicationContextInitializer
|
||||
* ApplicationContextInitializers} implementing
|
||||
* {@link org.springframework.core.Ordered Ordered} or marked with
|
||||
* {@link org.springframework.core.annotation.Order @Order} will be sorted
|
||||
* appropriately in conjunction with annotation-driven configuration in the
|
||||
* TestContext framework.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
// Note: the ordering of the config classes is intentionally: global, two, one.
|
||||
// Note: the ordering of the initializers is intentionally: two, one.
|
||||
@ContextConfiguration(classes = { GlobalConfig.class, ConfigTwo.class, ConfigOne.class }, initializers = {
|
||||
OrderedTwoInitializer.class, OrderedOneInitializer.class })
|
||||
public class OrderedInitializersAnnotationConfigTests {
|
||||
|
||||
private static final String PROFILE_GLOBAL = "global";
|
||||
private static final String PROFILE_ONE = "one";
|
||||
private static final String PROFILE_TWO = "two";
|
||||
|
||||
@Autowired
|
||||
private String foo, bar, baz;
|
||||
|
||||
|
||||
@Test
|
||||
public void activeBeans() {
|
||||
assertEquals(PROFILE_GLOBAL, foo);
|
||||
assertEquals(PROFILE_GLOBAL, bar);
|
||||
assertEquals(PROFILE_TWO, baz);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Configuration
|
||||
static class GlobalConfig {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return PROFILE_GLOBAL;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return PROFILE_GLOBAL;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public String baz() {
|
||||
return PROFILE_GLOBAL;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Profile(PROFILE_ONE)
|
||||
static class ConfigOne {
|
||||
|
||||
@Bean
|
||||
public String foo() {
|
||||
return PROFILE_ONE;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public String bar() {
|
||||
return PROFILE_ONE;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public String baz() {
|
||||
return PROFILE_ONE;
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Profile(PROFILE_TWO)
|
||||
static class ConfigTwo {
|
||||
|
||||
@Bean
|
||||
public String baz() {
|
||||
return PROFILE_TWO;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
static class OrderedOneInitializer implements ApplicationContextInitializer<GenericApplicationContext>, Ordered {
|
||||
|
||||
public void initialize(GenericApplicationContext applicationContext) {
|
||||
applicationContext.getEnvironment().setActiveProfiles(PROFILE_ONE);
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Order(2)
|
||||
static class OrderedTwoInitializer implements ApplicationContextInitializer<GenericApplicationContext> {
|
||||
|
||||
public void initialize(GenericApplicationContext applicationContext) {
|
||||
applicationContext.getEnvironment().setActiveProfiles(PROFILE_TWO);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.aci.annotation;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.aci.DevProfileInitializer;
|
||||
|
||||
/**
|
||||
* Integration tests that verify support for {@link ApplicationContextInitializer
|
||||
* ApplicationContextInitializers} in conjunction with annotation-driven
|
||||
* configuration in the TestContext framework.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
*/
|
||||
@ContextConfiguration(initializers = DevProfileInitializer.class, inheritInitializers = false)
|
||||
public class OverriddenInitializersAnnotationConfigTests extends SingleInitializerAnnotationConfigTests {
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void activeBeans() {
|
||||
assertEquals("foo", foo);
|
||||
assertNull(bar);
|
||||
assertEquals("dev profile config", baz);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.aci.annotation;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
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.context.ApplicationContextInitializer;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit4.aci.FooBarAliasInitializer;
|
||||
|
||||
/**
|
||||
* Integration tests that verify support for {@link ApplicationContextInitializer
|
||||
* ApplicationContextInitializers} in conjunction with annotation-driven
|
||||
* configuration in the TestContext framework.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { GlobalConfig.class, DevProfileConfig.class }, initializers = FooBarAliasInitializer.class)
|
||||
public class SingleInitializerAnnotationConfigTests {
|
||||
|
||||
@Autowired
|
||||
protected String foo;
|
||||
|
||||
@Autowired(required = false)
|
||||
@Qualifier("bar")
|
||||
protected String bar;
|
||||
|
||||
@Autowired
|
||||
protected String baz;
|
||||
|
||||
|
||||
@Test
|
||||
public void activeBeans() {
|
||||
assertEquals("foo", foo);
|
||||
assertEquals("foo", bar);
|
||||
assertEquals("global config", baz);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean id="foo" class="java.lang.String">
|
||||
<constructor-arg value="foo" />
|
||||
</bean>
|
||||
|
||||
<bean id="baz" class="java.lang.String">
|
||||
<constructor-arg value="global config" />
|
||||
</bean>
|
||||
|
||||
<beans profile="dev">
|
||||
<bean id="baz" class="java.lang.String">
|
||||
<constructor-arg value="dev profile config" />
|
||||
</bean>
|
||||
</beans>
|
||||
|
||||
</beans>
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.aci.xml;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.junit4.aci.DevProfileInitializer;
|
||||
import org.springframework.test.context.junit4.aci.FooBarAliasInitializer;
|
||||
|
||||
/**
|
||||
* Integration tests that verify support for {@link ApplicationContextInitializer
|
||||
* ApplicationContextInitializers} in conjunction with XML configuration files
|
||||
* in the TestContext framework.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(initializers = { FooBarAliasInitializer.class, DevProfileInitializer.class })
|
||||
public class MultipleInitializersXmlConfigTests {
|
||||
|
||||
@Autowired
|
||||
private String foo, bar, baz;
|
||||
|
||||
|
||||
@Test
|
||||
public void activeBeans() {
|
||||
assertEquals("foo", foo);
|
||||
assertEquals("foo", bar);
|
||||
assertEquals("dev profile config", baz);
|
||||
}
|
||||
|
||||
}
|
|
@ -59,8 +59,8 @@
|
|||
linkend="new-in-3.1-property-source-abstraction" />).
|
||||
<classname>MockEnvironment</classname> and
|
||||
<classname>MockPropertySource</classname> are useful for developing
|
||||
<emphasis>out-of-container</emphasis> unit tests for code that depends
|
||||
on environment-specific properties.</para>
|
||||
<emphasis>out-of-container</emphasis> tests for code that depends on
|
||||
environment-specific properties.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="mock-objects-jndi">
|
||||
|
@ -271,20 +271,20 @@
|
|||
container take time to instantiate. For example, a project with 50 to
|
||||
100 Hibernate mapping files might take 10 to 20 seconds to load the
|
||||
mapping files, and incurring that cost before running every test in
|
||||
every test fixture leads to slower overall test runs that could reduce
|
||||
productivity.</para>
|
||||
every test fixture leads to slower overall test runs that reduce
|
||||
developer productivity.</para>
|
||||
|
||||
<para>Test classes can provide either an array of <emphasis>resource
|
||||
locations</emphasis> for XML configuration metadata — typically in the
|
||||
classpath — or an array of <emphasis>annotated classes</emphasis> that
|
||||
is used to configure the application. These locations or classes are
|
||||
the same as or similar to those specified in
|
||||
<para>Test classes typically declare either an array of
|
||||
<emphasis>resource locations</emphasis> for XML configuration metadata
|
||||
— often in the classpath — or an array of <emphasis>annotated
|
||||
classes</emphasis> that is used to configure the application. These
|
||||
locations or classes are the same as or similar to those specified in
|
||||
<literal>web.xml</literal> or other deployment configuration
|
||||
files.</para>
|
||||
|
||||
<para>By default, once loaded, the configured
|
||||
<interfacename>ApplicationContext</interfacename> is reused for each
|
||||
test. Thus the setup cost is incurred only once (per test suite), and
|
||||
test. Thus the setup cost is incurred only once per test suite, and
|
||||
subsequent test execution is much faster. In this context, the term
|
||||
<emphasis>test suite</emphasis> means all tests run in the same JVM —
|
||||
for example, all tests run from an Ant, Maven, or Gradle build for a
|
||||
|
@ -311,11 +311,10 @@
|
|||
contexts across various testing scenarios (e.g., for configuring
|
||||
Spring-managed object graphs, transactional proxies,
|
||||
<classname>DataSource</classname>s, etc.), thus avoiding the need to
|
||||
duplicate complex test fixture set up for individual test
|
||||
cases.</para>
|
||||
duplicate complex test fixture setup for individual test cases.</para>
|
||||
|
||||
<para>As an example, consider the scenario where we have a class,
|
||||
<classname>HibernateTitleRepository</classname>, that performs data
|
||||
<classname>HibernateTitleRepository</classname>, that implements data
|
||||
access logic for a <classname>Title</classname> domain entity. We want
|
||||
to write integration tests that test the following areas:</para>
|
||||
|
||||
|
@ -348,7 +347,7 @@
|
|||
<title>Transaction management</title>
|
||||
|
||||
<para>One common issue in tests that access a real database is their
|
||||
affect on the state of the persistence store. Even when you're using a
|
||||
effect on the state of the persistence store. Even when you're using a
|
||||
development database, changes to the state may affect future tests.
|
||||
Also, many operations — such as inserting or modifying persistent data
|
||||
— cannot be performed (or verified) outside a transaction.</para>
|
||||
|
@ -358,11 +357,11 @@
|
|||
simply write code that can assume the existence of a transaction. If
|
||||
you call transactionally proxied objects in your tests, they will
|
||||
behave correctly, according to their configured transactional
|
||||
semantics. In addition, if test methods delete the contents of
|
||||
selected tables while running within a transaction, the transaction
|
||||
will roll back by default, and the database will return to its state
|
||||
prior to execution of the test. Transactional support is provided to
|
||||
your test class via a
|
||||
semantics. In addition, if a test method deletes the contents of
|
||||
selected tables while running within the transaction managed for the
|
||||
test, the transaction will roll back by default, and the database will
|
||||
return to its state prior to execution of the test. Transactional
|
||||
support is provided to a test via a
|
||||
<classname>PlatformTransactionManager</classname> bean defined in the
|
||||
test's application context.</para>
|
||||
|
||||
|
@ -370,10 +369,10 @@
|
|||
useful when you want a particular test to populate or modify the
|
||||
database — the TestContext framework can be instructed to cause the
|
||||
transaction to commit instead of roll back via the <link
|
||||
linkend="integration-testing-annotations">
|
||||
<interfacename>@TransactionConfiguration</interfacename> </link> and
|
||||
<link linkend="integration-testing-annotations">
|
||||
<interfacename>@Rollback</interfacename> </link> annotations.</para>
|
||||
linkend="integration-testing-annotations"><interfacename>@TransactionConfiguration</interfacename></link>
|
||||
and <link
|
||||
linkend="integration-testing-annotations"><interfacename>@Rollback</interfacename></link>
|
||||
annotations.</para>
|
||||
|
||||
<para>See transaction management with the <link
|
||||
linkend="testcontext-tx">TestContext framework</link>.</para>
|
||||
|
@ -396,8 +395,8 @@
|
|||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>A <classname>JdbcTemplate</classname>, for executing
|
||||
SQL statements to query the database. Such queries can be used to
|
||||
<para>A <classname>JdbcTemplate</classname>, for executing SQL
|
||||
statements to query the database. Such queries can be used to
|
||||
confirm database state both <emphasis>prior to</emphasis> and
|
||||
<emphasis>after</emphasis> execution of database-related
|
||||
application code, and Spring ensures that such queries run in the
|
||||
|
@ -422,14 +421,13 @@
|
|||
<title>JDBC Testing Support</title>
|
||||
|
||||
<para>The <literal>org.springframework.test.jdbc</literal> package
|
||||
contains <classname>JdbcTestUtils</classname>, which is a
|
||||
collection of JDBC related utility functions intended to simplify
|
||||
standard database testing scenarios. <emphasis>Note that <link
|
||||
linkend="testcontext-support-classes-junit4">
|
||||
<classname>AbstractTransactionalJUnit4SpringContextTests</classname>
|
||||
</link> and <link linkend="testcontext-support-classes-testng">
|
||||
<classname>AbstractTransactionalTestNGSpringContextTests</classname>
|
||||
</link> provide convenience methods which delegate to
|
||||
contains <classname>JdbcTestUtils</classname>, which is a collection of
|
||||
JDBC related utility functions intended to simplify standard database
|
||||
testing scenarios. <emphasis>Note that <link
|
||||
linkend="testcontext-support-classes-junit4"><classname>AbstractTransactionalJUnit4SpringContextTests</classname></link>
|
||||
and <link
|
||||
linkend="testcontext-support-classes-testng"><classname>AbstractTransactionalTestNGSpringContextTests</classname></link>
|
||||
provide convenience methods which delegate to
|
||||
<classname>JdbcTestUtils</classname> internally.</emphasis></para>
|
||||
|
||||
<para>The <literal>spring-jdbc</literal> module provides support for
|
||||
|
@ -460,8 +458,8 @@
|
|||
|
||||
<para>Defines class-level metadata that is used to determine how
|
||||
to load and configure an
|
||||
<interfacename>ApplicationContext</interfacename> for test
|
||||
classes. Specifically,
|
||||
<interfacename>ApplicationContext</interfacename> for integration
|
||||
tests. Specifically,
|
||||
<interfacename>@ContextConfiguration</interfacename> declares
|
||||
<emphasis>either</emphasis> the application context resource
|
||||
<varname>locations</varname> <emphasis>or</emphasis> the annotated
|
||||
|
@ -471,8 +469,8 @@
|
|||
<para>Resource locations are typically XML configuration files
|
||||
located in the classpath; whereas, annotated classes are typically
|
||||
<interfacename>@Configuration</interfacename> classes. However,
|
||||
resource locations could also refer to files in the file system,
|
||||
and annotated classes could be component classes, etc.</para>
|
||||
resource locations can also refer to files in the file system, and
|
||||
annotated classes can be component classes, etc.</para>
|
||||
|
||||
<programlisting language="java"><emphasis role="bold">@ContextConfiguration</emphasis>("/test-config.xml")
|
||||
public class XmlApplicationContextTests {
|
||||
|
@ -485,13 +483,27 @@ public class ConfigClassApplicationContextTests {
|
|||
<lineannotation>// class body...</lineannotation>
|
||||
}</programlisting>
|
||||
|
||||
<para>As an alternative or in addition to declaring resource
|
||||
locations or annotated classes,
|
||||
<interfacename>@ContextConfiguration</interfacename> may be used
|
||||
to declare
|
||||
<interfacename>ApplicationContextInitializer</interfacename>
|
||||
classes.</para>
|
||||
|
||||
<programlisting language="java"><emphasis role="bold">@ContextConfiguration</emphasis>(<emphasis
|
||||
role="bold">initializers</emphasis>=CustomContextIntializer.class)
|
||||
public class ContextInitializerTests {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
}</programlisting>
|
||||
|
||||
<para><interfacename>@ContextConfiguration</interfacename> may
|
||||
optionally be used to declare the
|
||||
<interfacename>ContextLoader</interfacename> strategy as well.
|
||||
Note, however, that you typically do not need to explicitly
|
||||
configure the loader since the default loader supports either
|
||||
resource <varname>locations</varname> or annotated
|
||||
<varname>classes</varname>.</para>
|
||||
<varname>classes</varname> as well as
|
||||
<varname>initializers</varname>.</para>
|
||||
|
||||
<programlisting language="java"><emphasis role="bold">@ContextConfiguration</emphasis>(<emphasis
|
||||
role="bold">locations</emphasis>="/test-context.xml", <emphasis
|
||||
|
@ -503,8 +515,8 @@ public class CustomLoaderXmlApplicationContextTests {
|
|||
<note>
|
||||
<para><interfacename>@ContextConfiguration</interfacename>
|
||||
provides support for <emphasis>inheriting</emphasis> resource
|
||||
locations or configuration classes declared by superclasses by
|
||||
default.</para>
|
||||
locations or configuration classes as well as context
|
||||
initializers declared by superclasses by default.</para>
|
||||
</note>
|
||||
|
||||
<para>See <link linkend="testcontext-ctx-management">Context
|
||||
|
@ -650,8 +662,8 @@ public class CustomTestExecutionListenerTests {
|
|||
should be used to drive transactions can be explicitly specified
|
||||
if there are multiple beans of type
|
||||
<interfacename>PlatformTransactionManager</interfacename> in the
|
||||
test's <interfacename>ApplicationContext</interfacename> and the
|
||||
bean name of the desired
|
||||
test's <interfacename>ApplicationContext</interfacename> and if
|
||||
the bean name of the desired
|
||||
<interfacename>PlatformTransactionManager</interfacename> is not
|
||||
"transactionManager". In addition, you can change the
|
||||
<literal>defaultRollback</literal> flag to
|
||||
|
@ -1227,15 +1239,21 @@ public class MyTest {
|
|||
application context resource <literal>locations</literal> or annotated
|
||||
<varname>classes</varname>, the configured
|
||||
<interfacename>ContextLoader</interfacename> determines how to load a
|
||||
context from a default location or default configuration
|
||||
classes.</para>
|
||||
context from a default location or default configuration classes. In
|
||||
addition to context resource <varname>locations</varname> and
|
||||
annotated <varname>classes</varname>, an application context can also
|
||||
be configured via application context
|
||||
<varname>initializers</varname>.</para>
|
||||
|
||||
<para>The following sections explain how to configure an
|
||||
<interfacename>ApplicationContext</interfacename> via XML
|
||||
configuration files or annotated classes (typically
|
||||
<interfacename>@Configuration</interfacename> classes) using Spring's
|
||||
<interfacename>@ContextConfiguration</interfacename>
|
||||
annotation.</para>
|
||||
configuration files, annotated classes (typically
|
||||
<interfacename>@Configuration</interfacename> classes), or context
|
||||
initializers using Spring's
|
||||
<interfacename>@ContextConfiguration</interfacename> annotation.
|
||||
Alternatively, you can implement and configure your own custom
|
||||
<interfacename>SmartContextLoader</interfacename> for advanced use
|
||||
cases.</para>
|
||||
|
||||
<section xml:id="testcontext-ctx-management-xml">
|
||||
<title>Context configuration with XML resources</title>
|
||||
|
@ -1245,18 +1263,16 @@ public class MyTest {
|
|||
class with <interfacename>@ContextConfiguration</interfacename> and
|
||||
configure the <literal>locations</literal> attribute with an array
|
||||
that contains the resource locations of XML configuration metadata.
|
||||
A plain path — for example <literal>"context.xml"</literal> — will
|
||||
be treated as a classpath resource that is relative to the package
|
||||
in which the test class is defined. A path starting with a slash is
|
||||
treated as an absolute classpath location, for example
|
||||
A plain or relative path — for example
|
||||
<literal>"context.xml"</literal> — will be treated as a classpath
|
||||
resource that is relative to the package in which the test class is
|
||||
defined. A path starting with a slash is treated as an absolute
|
||||
classpath location, for example
|
||||
<literal>"/org/example/config.xml"</literal>. A path which
|
||||
represents a resource URL (i.e., a path prefixed with
|
||||
<literal>classpath:</literal>, <literal>file:</literal>,
|
||||
<literal>http:</literal>, etc.) will be used <emphasis>as
|
||||
is</emphasis>. Alternatively, you can implement and configure your
|
||||
own custom <interfacename>ContextLoader</interfacename> or
|
||||
<interfacename>SmartContextLoader</interfacename> for advanced use
|
||||
cases.</para>
|
||||
is</emphasis>.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be loaded from "/app-config.xml" and
|
||||
|
@ -1269,10 +1285,10 @@ public class MyTest {
|
|||
<para><interfacename>@ContextConfiguration</interfacename> supports
|
||||
an alias for the <literal>locations</literal> attribute through the
|
||||
standard Java <literal>value</literal> attribute. Thus, if you do
|
||||
not need to configure a custom
|
||||
<interfacename>ContextLoader</interfacename>, you can omit the
|
||||
declaration of the <literal>locations</literal> attribute name and
|
||||
declare the resource locations by using the shorthand format
|
||||
not need to declare additional attributes in
|
||||
<interfacename>@ContextConfiguration</interfacename>, you can omit
|
||||
the declaration of the <literal>locations</literal> attribute name
|
||||
and declare the resource locations by using the shorthand format
|
||||
demonstrated in the following example.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
|
@ -1296,7 +1312,8 @@ public class MyTest {
|
|||
<programlisting language="java">package com.example;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be loaded from "classpath:/com/example/MyTest-context.xml"</lineannotation>
|
||||
<lineannotation>// ApplicationContext will be loaded from
|
||||
// "classpath:/com/example/MyTest-context.xml"</lineannotation>
|
||||
<emphasis role="bold">@ContextConfiguration</emphasis>
|
||||
public class MyTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
|
@ -1311,15 +1328,11 @@ public class MyTest {
|
|||
<xref linkend="beans-java" />), annotate your test class with
|
||||
<interfacename>@ContextConfiguration</interfacename> and configure
|
||||
the <literal>classes</literal> attribute with an array that contains
|
||||
references to annotated classes. Alternatively, you can implement
|
||||
and configure your own custom
|
||||
<interfacename>ContextLoader</interfacename> or
|
||||
<interfacename>SmartContextLoader</interfacename> for advanced use
|
||||
cases.</para>
|
||||
references to annotated classes.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be loaded from AppConfig and TestConfig</lineannotation>
|
||||
<emphasis role="bold">@ContextConfiguration(classes={AppConfig.class, TestConfig.class})</emphasis>
|
||||
<emphasis role="bold">@ContextConfiguration(classes = {AppConfig.class, TestConfig.class})</emphasis>
|
||||
public class MyTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
}</programlisting>
|
||||
|
@ -1340,10 +1353,9 @@ public class MyTest {
|
|||
arbitrary. In addition, a test class can contain more than one
|
||||
static inner configuration class if desired.</para>
|
||||
|
||||
<programlisting language="java">package com.example;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be loaded from the static inner Config class</lineannotation>
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be loaded from the
|
||||
// static inner Config class</lineannotation>
|
||||
<emphasis role="bold">@ContextConfiguration</emphasis>
|
||||
public class OrderServiceTest {
|
||||
|
||||
|
@ -1406,27 +1418,85 @@ public class OrderServiceTest {
|
|||
other type of configuration.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="testcontext-ctx-management-initializers">
|
||||
<title>Context configuration with context initializers</title>
|
||||
|
||||
<para>To configure an
|
||||
<interfacename>ApplicationContext</interfacename> for your tests
|
||||
using context initializers, annotate your test class with
|
||||
<interfacename>@ContextConfiguration</interfacename> and configure
|
||||
the <literal>initializers</literal> attribute with an array that
|
||||
contains references to classes that implement
|
||||
<interfacename>ApplicationContextInitializer</interfacename>. The
|
||||
declared context initializers will then be used to initialize the
|
||||
<interfacename>ConfigurableApplicationContext</interfacename> that
|
||||
is loaded for your tests. Note that the concrete
|
||||
<interfacename>ConfigurableApplicationContext</interfacename> type
|
||||
supported by each declared initializer must be compatible with the
|
||||
type of <interfacename>ApplicationContext</interfacename> created by
|
||||
the <interfacename>SmartContextLoader</interfacename> in use (i.e.,
|
||||
typically a <classname>GenericApplicationContext</classname>).
|
||||
Furthermore, the order in which the initializers are invoked depends
|
||||
on whether they implement Spring's
|
||||
<interfacename>Ordered</interfacename> interface or are annotated
|
||||
with Spring's <interfacename>@Order</interfacename>
|
||||
annotation.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be loaded from TestConfig
|
||||
</lineannotation><lineannotation>// and initialized by TestAppCtxInitializer</lineannotation>
|
||||
<emphasis role="bold">@ContextConfiguration(
|
||||
classes = TestConfig.class,
|
||||
initializers = TestAppCtxInitializer.class)</emphasis>
|
||||
public class MyTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
}</programlisting>
|
||||
|
||||
<para>It is also possible to omit the declaration of XML
|
||||
configuration files or annotated classes in
|
||||
<interfacename>@ContextConfiguration</interfacename> entirely and
|
||||
instead declare only
|
||||
<interfacename>ApplicationContextInitializer</interfacename> classes
|
||||
which are then responsible for registering beans in the context —
|
||||
for example, by programmatically loading bean definitions from XML
|
||||
files or configuration classes.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be initialized by EntireAppInitializer
|
||||
</lineannotation><lineannotation>// which presumably registers beans in the context</lineannotation>
|
||||
<emphasis role="bold">@ContextConfiguration(initializers = EntireAppInitializer.class)</emphasis>
|
||||
public class MyTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
}</programlisting>
|
||||
</section>
|
||||
|
||||
<section xml:id="testcontext-ctx-management-inheritance">
|
||||
<title>Context configuration inheritance</title>
|
||||
|
||||
<para><interfacename>@ContextConfiguration</interfacename> supports
|
||||
a boolean <literal>inheritLocations</literal> attribute that denotes
|
||||
whether resource locations or annotated classes declared by
|
||||
superclasses should be <emphasis>inherited</emphasis>. The default
|
||||
value is <literal>true</literal>. This means that a test class
|
||||
inherits the resource locations or annotated classes declared by any
|
||||
superclasses. Specifically, the resource locations or annotated
|
||||
classes for a test class are appended to the list of resource
|
||||
locations or annotated classes declared by superclasses. Thus,
|
||||
subclasses have the option of <emphasis>extending</emphasis> the
|
||||
list of resource locations or annotated classes.</para>
|
||||
boolean <varname>inheritLocations</varname> and
|
||||
<varname>inheritInitializers</varname> attributes that denote
|
||||
whether resource locations or annotated classes and context
|
||||
initializers declared by superclasses should be
|
||||
<emphasis>inherited</emphasis>. The default value for both flags is
|
||||
<literal>true</literal>. This means that a test class inherits the
|
||||
resource locations or annotated classes as well as the context
|
||||
initializers declared by any superclasses. Specifically, the
|
||||
resource locations or annotated classes for a test class are
|
||||
appended to the list of resource locations or annotated classes
|
||||
declared by superclasses. Similarly, the initializers for a given
|
||||
test class will be added to the set of initializers defined by test
|
||||
superclasses. Thus, subclasses have the option of
|
||||
<emphasis>extending</emphasis> the resource locations, annotated
|
||||
classes, or context initializers.</para>
|
||||
|
||||
<para>If <interfacename>@ContextConfiguration</interfacename>'s
|
||||
<literal>inheritLocations</literal> attribute is set to
|
||||
<literal>inheritLocations</literal> or
|
||||
<varname>inheritInitializers</varname> attribute is set to
|
||||
<literal>false</literal>, the resource locations or annotated
|
||||
classes for the test class <emphasis>shadow</emphasis> and
|
||||
effectively replace any resource locations or annotated classes
|
||||
defined by superclasses.</para>
|
||||
classes and the context initializers, respectively, for the test
|
||||
class <emphasis>shadow</emphasis> and effectively replace the
|
||||
configuration defined by superclasses.</para>
|
||||
|
||||
<para>In the following example that uses XML resource locations, the
|
||||
<interfacename>ApplicationContext</interfacename> for
|
||||
|
@ -1439,14 +1509,15 @@ public class OrderServiceTest {
|
|||
<emphasis>"base-config.xml"</emphasis>.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be loaded from "/base-config.xml" in the root of the classpath</lineannotation>
|
||||
<lineannotation>// ApplicationContext will be loaded from "/base-config.xml"
|
||||
// in the root of the classpath</lineannotation>
|
||||
<emphasis role="bold">@ContextConfiguration("/base-config.xml")</emphasis>
|
||||
public class BaseTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
}
|
||||
|
||||
<lineannotation>// ApplicationContext will be loaded from "/base-config.xml" and "/extended-config.xml"</lineannotation>
|
||||
<lineannotation>// in the root of the classpath</lineannotation>
|
||||
<lineannotation>// ApplicationContext will be loaded from "/base-config.xml" and
|
||||
// "/extended-config.xml" </lineannotation><lineannotation>in the root of the classpath</lineannotation>
|
||||
<emphasis role="bold">@ContextConfiguration("/extended-config.xml")</emphasis>
|
||||
public class ExtendedTest extends BaseTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
|
@ -1463,13 +1534,38 @@ public class ExtendedTest extends BaseTest {
|
|||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be loaded from BaseConfig</lineannotation>
|
||||
<emphasis role="bold">@ContextConfiguration(classes=BaseConfig.class)</emphasis>
|
||||
<emphasis role="bold">@ContextConfiguration(classes = BaseConfig.class)</emphasis>
|
||||
public class BaseTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
}
|
||||
|
||||
<lineannotation>// ApplicationContext will be loaded from BaseConfig and ExtendedConfig</lineannotation>
|
||||
<emphasis role="bold">@ContextConfiguration(classes=ExtendedConfig.class)</emphasis>
|
||||
<emphasis role="bold">@ContextConfiguration(classes = ExtendedConfig.class)</emphasis>
|
||||
public class ExtendedTest extends BaseTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
}</programlisting>
|
||||
|
||||
<para>In the following example that uses context initializers, the
|
||||
<interfacename>ApplicationContext</interfacename> for
|
||||
<classname>ExtendedTest</classname> will be initialized using
|
||||
<classname>BaseInitializer</classname> <emphasis
|
||||
role="bold">and</emphasis>
|
||||
<classname>ExtendedInitializer</classname>. Note, however, that the
|
||||
order in which the initializers are invoked depends on whether they
|
||||
implement Spring's <interfacename>Ordered</interfacename> interface
|
||||
or are annotated with Spring's <interfacename>@Order</interfacename>
|
||||
annotation.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be initialized by BaseInitializer</lineannotation>
|
||||
<emphasis role="bold">@ContextConfiguration(initializers=BaseInitializer.class)</emphasis>
|
||||
public class BaseTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
}
|
||||
|
||||
<lineannotation>// ApplicationContext will be initialized by BaseInitializer
|
||||
// and ExtendedInitializer</lineannotation>
|
||||
<emphasis role="bold">@ContextConfiguration(initializers=ExtendedInitializer.class)</emphasis>
|
||||
public class ExtendedTest extends BaseTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
}</programlisting>
|
||||
|
@ -1478,9 +1574,9 @@ public class ExtendedTest extends BaseTest {
|
|||
<section xml:id="testcontext-ctx-management-env-profiles">
|
||||
<title>Context configuration with environment profiles</title>
|
||||
|
||||
<para>Spring 3.1 introduces first-class support in the framework for
|
||||
<para>Spring 3.1 introduced first-class support in the framework for
|
||||
the notion of environments and profiles (a.k.a., <emphasis>bean
|
||||
definition profiles</emphasis>), and integration tests can now be
|
||||
definition profiles</emphasis>), and integration tests can be
|
||||
configured to activate particular bean definition profiles for
|
||||
various testing scenarios. This is achieved by annotating a test
|
||||
class with the <interfacename>@ActiveProfiles</interfacename>
|
||||
|
@ -1634,7 +1730,7 @@ public class TransferServiceConfig {
|
|||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(
|
||||
classes={
|
||||
classes = {
|
||||
TransferServiceConfig.class,
|
||||
StandaloneDataConfig.class,
|
||||
JndiDataConfig.class})
|
||||
|
@ -1715,6 +1811,11 @@ public class TransferServiceTest {
|
|||
@ContextConfiguration)</emphasis></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><varname>contextInitializerClasses</varname>
|
||||
<emphasis>(from @ContextConfiguration)</emphasis></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><varname>contextLoader</varname> <emphasis>(from
|
||||
@ContextConfiguration)</emphasis></para>
|
||||
|
@ -1737,8 +1838,8 @@ public class TransferServiceTest {
|
|||
also defines <literal>{"app-config.xml",
|
||||
"test-config.xml"}</literal> for its locations (either explicitly or
|
||||
implicitly through inheritance) and does not define a different
|
||||
<interfacename>ContextLoader</interfacename> or different active
|
||||
profiles, then the same
|
||||
<interfacename>ContextLoader</interfacename>, different active
|
||||
profiles, or different context initializers, then the same
|
||||
<interfacename>ApplicationContext</interfacename> will be shared by
|
||||
both test classes. This means that the setup cost for loading an
|
||||
application context is incurred only once (per test suite), and
|
||||
|
@ -2103,7 +2204,7 @@ public void updateWithSessionFlush() {
|
|||
</section>
|
||||
|
||||
<section xml:id="testcontext-support-classes">
|
||||
<title>TestContext support classes</title>
|
||||
<title>TestContext Framework support classes</title>
|
||||
|
||||
<section xml:id="testcontext-support-classes-junit4">
|
||||
<title>JUnit support classes</title>
|
||||
|
@ -2157,14 +2258,14 @@ public void updateWithSessionFlush() {
|
|||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>jdbcTemplate</literal>: Use this
|
||||
variable to execute SQL statements to query the database.
|
||||
Such queries can be used to confirm database state both
|
||||
<emphasis>prior to</emphasis> and <emphasis>after</emphasis>
|
||||
execution of database-related application code, and Spring
|
||||
ensures that such queries run in the scope of the same
|
||||
transaction as the application code. When used in
|
||||
conjunction with an ORM tool, be sure to avoid <link
|
||||
<para><literal>jdbcTemplate</literal>: Use this variable to
|
||||
execute SQL statements to query the database. Such queries
|
||||
can be used to confirm database state both <emphasis>prior
|
||||
to</emphasis> and <emphasis>after</emphasis> execution of
|
||||
database-related application code, and Spring ensures that
|
||||
such queries run in the scope of the same transaction as the
|
||||
application code. When used in conjunction with an ORM tool,
|
||||
be sure to avoid <link
|
||||
linkend="testcontext-tx-false-positives">false
|
||||
positives</link>.</para>
|
||||
</listitem>
|
||||
|
@ -2266,14 +2367,14 @@ public class SimpleTest {
|
|||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><literal>jdbcTemplate</literal>: Use this
|
||||
variable to execute SQL statements to query the database.
|
||||
Such queries can be used to confirm database state both
|
||||
<emphasis>prior to</emphasis> and <emphasis>after</emphasis>
|
||||
execution of database-related application code, and Spring
|
||||
ensures that such queries run in the scope of the same
|
||||
transaction as the application code. When used in
|
||||
conjunction with an ORM tool, be sure to avoid <link
|
||||
<para><literal>jdbcTemplate</literal>: Use this variable to
|
||||
execute SQL statements to query the database. Such queries
|
||||
can be used to confirm database state both <emphasis>prior
|
||||
to</emphasis> and <emphasis>after</emphasis> execution of
|
||||
database-related application code, and Spring ensures that
|
||||
such queries run in the scope of the same transaction as the
|
||||
application code. When used in conjunction with an ORM tool,
|
||||
be sure to avoid <link
|
||||
linkend="testcontext-tx-false-positives">false
|
||||
positives</link>.</para>
|
||||
</listitem>
|
||||
|
|
Loading…
Reference in New Issue