Merge pull request #121 from sbrannen/SPR-9011
* SPR-9011: Support ApplicationContextInitializers in the TCF
This commit is contained in:
commit
58daeea1e2
|
|
@ -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