Support Groovy scripts in the TCF
Spring Framework 4.0 introduced first-class support for a Groovy-based DSL for defining the beans for an ApplicationContext. However, prior to this commit, the Spring TestContext Framework (TCF) did not provide any out-of-the-box support for using Groovy scripts as path-based resource locations when loading an application context for tests. This commit addresses this issue by introducing first-class support for using Groovy scripts to load the ApplicationContext for integration tests managed by the TCF. Specifically, the following changes have been made in the TCF to support Groovy scripts. - Introduced getResourceSuffixes() in AbstractContextLoader in order to support multiple resource suffixes in the default detection process. This feature is used by the new Groovy/Xml context loaders. - Introduced GenericGroovyXmlContextLoader and GenericGroovyXmlWebContextLoader which support both Groovy scripts and XML config files for loading bean definitions. Furthermore, these loaders support "-context.xml" and "Context.groovy" as resource suffixes when detecting defaults. Note that a default XML config file will be detected before a default Groovy script. - DelegatingSmartContextLoader and WebDelegatingSmartContextLoader now use reflection to choose between using GenericGroovyXmlContextLoader and GenericGroovyXmlWebContextLoader vs. GenericXmlContextLoader and GenericXmlWebContextLoader as their XML loaders, depending on whether Groovy is present in the classpath. - Groovy scripts can be configured via the 'locations' or 'value' attributes of @ContextConfiguration and can be mixed seamlessly with XML config files. Issue: SPR-11233
This commit is contained in:
parent
d4fe732f46
commit
35c372f200
|
@ -929,6 +929,7 @@ project("spring-test") {
|
|||
optional("javax.portlet:portlet-api:2.0")
|
||||
optional("javax.el:javax.el-api:2.2.5")
|
||||
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
|
||||
optional("org.hamcrest:hamcrest-core:1.3")
|
||||
optional("com.jayway.jsonpath:json-path:0.9.0")
|
||||
optional("org.skyscreamer:jsonassert:1.2.3")
|
||||
|
|
|
@ -27,48 +27,52 @@ import org.springframework.context.ApplicationContextInitializer;
|
|||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
/**
|
||||
* {@code @ContextConfiguration} defines class-level metadata that is
|
||||
* used to determine how to load and configure an
|
||||
* {@link org.springframework.context.ApplicationContext ApplicationContext}
|
||||
* for integration tests.
|
||||
* {@code @ContextConfiguration} defines class-level metadata that is used to determine
|
||||
* how to load and configure an {@link org.springframework.context.ApplicationContext
|
||||
* ApplicationContext} 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, {@linkplain #loader context loaders} may choose to support
|
||||
* <em>either</em> path-based <em>or</em> class-based resources. As of Spring
|
||||
* 4.0.4, {@linkplain #loader context loaders} may choose to support path-based
|
||||
* <p>
|
||||
* Prior to Spring 3.1, only path-based resource locations (typically XML configuration
|
||||
* files) were supported. As of Spring 3.1, {@linkplain #loader context loaders} may
|
||||
* choose to support <em>either</em> path-based <em>or</em> class-based resources. As of
|
||||
* Spring 4.0.4, {@linkplain #loader context loaders} may choose to support path-based
|
||||
* <em>and</em> class-based resources simultaneously. Consequently
|
||||
* {@code @ContextConfiguration} can be used to declare either path-based
|
||||
* resource locations (via the {@link #locations} or {@link #value} attribute)
|
||||
* <em>or</em> annotated classes (via the {@link #classes} attribute). Note,
|
||||
* however, that most implementations of {@link SmartContextLoader} only support
|
||||
* a single resource type.
|
||||
* {@code @ContextConfiguration} can be used to declare either path-based resource
|
||||
* locations (via the {@link #locations} or {@link #value} attribute) <em>or</em>
|
||||
* annotated classes (via the {@link #classes} attribute). Note, however, that most
|
||||
* implementations of {@link SmartContextLoader} only support a single resource type. As
|
||||
* of Spring 4.1, path-based resource locations may be either XML configuration files or
|
||||
* Groovy scripts (if Groovy is on the classpath). Of course, third-party frameworks may
|
||||
* choose to support additional types of path-based resources.
|
||||
*
|
||||
* <h3>Annotated Classes</h3>
|
||||
*
|
||||
* <p>The term <em>annotated class</em> can refer to any of the following.
|
||||
* <p>
|
||||
* The term <em>annotated class</em> can refer to any of the following.
|
||||
*
|
||||
* <ul>
|
||||
* <li>A class annotated with
|
||||
* {@link org.springframework.context.annotation.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 org.springframework.context.annotation.Bean @Bean}-methods</li>
|
||||
* <li>Any other class that contains {@link org.springframework.context.annotation.Bean
|
||||
* @Bean}-methods</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>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
|
||||
* <p>
|
||||
* 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>.
|
||||
*
|
||||
* <p>As of Spring Framework 4.0, this annotation may be used as a
|
||||
* <em>meta-annotation</em> to create custom <em>composed annotations</em>.
|
||||
* <p>
|
||||
* As of Spring Framework 4.0, this annotation may be used as a <em>meta-annotation</em>
|
||||
* to create custom <em>composed annotations</em>.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 2.5
|
||||
|
@ -104,20 +108,20 @@ public @interface ContextConfiguration {
|
|||
* <p>Check out the Javadoc for
|
||||
* {@link org.springframework.test.context.support.AbstractContextLoader#modifyLocations
|
||||
* AbstractContextLoader.modifyLocations()} for details on how a location
|
||||
* String will be interpreted at runtime, in particular in case of a relative
|
||||
* will be interpreted at runtime, in particular in case of a relative
|
||||
* path. Also, check out the documentation on
|
||||
* {@link org.springframework.test.context.support.AbstractContextLoader#generateDefaultLocations
|
||||
* AbstractContextLoader.generateDefaultLocations()} for details on the default
|
||||
* locations that are going to be used if none are specified.
|
||||
* AbstractContextLoader.generateDefaultLocations()} for details on the
|
||||
* default locations that are going to be used if none are specified.
|
||||
*
|
||||
* <p>Note that the above-mentioned default rules only apply for a standard
|
||||
* <p>Note that the aforementioned default rules only apply for a standard
|
||||
* {@link org.springframework.test.context.support.AbstractContextLoader
|
||||
* AbstractContextLoader} subclass such as
|
||||
* {@link org.springframework.test.context.support.GenericXmlContextLoader
|
||||
* GenericXmlContextLoader} which is the effective default implementation
|
||||
* used at runtime if {@code locations} are configured. See the
|
||||
* documentation for {@link #loader} for further details regarding default
|
||||
* loaders.
|
||||
* {@link org.springframework.test.context.support.GenericXmlContextLoader GenericXmlContextLoader} or
|
||||
* {@link org.springframework.test.context.support.GenericGroovyXmlContextLoader GenericGroovyXmlContextLoader}
|
||||
* which are the effective default implementations used at runtime if
|
||||
* {@code locations} are configured. See the documentation for {@link #loader}
|
||||
* for further details regarding default loaders.
|
||||
*
|
||||
* <p>This attribute may <strong>not</strong> be used in conjunction with
|
||||
* {@link #value}, but it may be used instead of {@link #value}.
|
||||
|
@ -186,17 +190,17 @@ public @interface ContextConfiguration {
|
|||
* <p>In the following example that uses path-based resource locations, the
|
||||
* {@link org.springframework.context.ApplicationContext ApplicationContext}
|
||||
* for {@code ExtendedTest} will be loaded from
|
||||
* "base-context.xml" <strong>and</strong>
|
||||
* "extended-context.xml", in that order. Beans defined in
|
||||
* "extended-context.xml" may therefore override those defined in
|
||||
* "base-context.xml".
|
||||
* {@code "base-context.xml"} <strong>and</strong>
|
||||
* {@code "extended-context.xml"}, in that order. Beans defined in
|
||||
* {@code "extended-context.xml"} may therefore override those defined
|
||||
* in {@code "base-context.xml"}.
|
||||
* <pre class="code">
|
||||
* @ContextConfiguration("base-context.xml")
|
||||
* @ContextConfiguration("base-context.xml")
|
||||
* public class BaseTest {
|
||||
* // ...
|
||||
* }
|
||||
*
|
||||
* @ContextConfiguration("extended-context.xml")
|
||||
* @ContextConfiguration("extended-context.xml")
|
||||
* public class ExtendedTest extends BaseTest {
|
||||
* // ...
|
||||
* }
|
||||
|
@ -281,16 +285,13 @@ public @interface ContextConfiguration {
|
|||
* {@link org.springframework.test.context.web.WebAppConfiguration
|
||||
* @WebAppConfiguration}. For further details on the default behavior
|
||||
* of various concrete {@code SmartContextLoaders}, check out the Javadoc for
|
||||
* {@link org.springframework.test.context.support.AbstractContextLoader
|
||||
* AbstractContextLoader},
|
||||
* {@link org.springframework.test.context.support.GenericXmlContextLoader
|
||||
* GenericXmlContextLoader},
|
||||
* {@link org.springframework.test.context.support.AnnotationConfigContextLoader
|
||||
* AnnotationConfigContextLoader},
|
||||
* {@link org.springframework.test.context.web.GenericXmlWebContextLoader
|
||||
* GenericXmlWebContextLoader}, and
|
||||
* {@link org.springframework.test.context.web.AnnotationConfigWebContextLoader
|
||||
* AnnotationConfigWebContextLoader}.
|
||||
* {@link org.springframework.test.context.support.AbstractContextLoader AbstractContextLoader},
|
||||
* {@link org.springframework.test.context.support.GenericXmlContextLoader GenericXmlContextLoader},
|
||||
* {@link org.springframework.test.context.support.GenericGroovyXmlContextLoader GenericGroovyXmlContextLoader},
|
||||
* {@link org.springframework.test.context.support.AnnotationConfigContextLoader AnnotationConfigContextLoader},
|
||||
* {@link org.springframework.test.context.web.GenericXmlWebContextLoader GenericXmlWebContextLoader},
|
||||
* {@link org.springframework.test.context.web.GenericGroovyXmlWebContextLoader GenericGroovyXmlWebContextLoader}, and
|
||||
* {@link org.springframework.test.context.web.AnnotationConfigWebContextLoader AnnotationConfigWebContextLoader}.
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
|
|
|
@ -55,6 +55,7 @@ import org.springframework.util.ResourceUtils;
|
|||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
* @see #generateDefaultLocations
|
||||
* @see #getResourceSuffixes
|
||||
* @see #modifyLocations
|
||||
*/
|
||||
public abstract class AbstractContextLoader implements SmartContextLoader {
|
||||
|
@ -144,14 +145,14 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
|
|||
// --- ContextLoader -------------------------------------------------------
|
||||
|
||||
/**
|
||||
* If the supplied {@code locations} are {@code null} or
|
||||
* <em>empty</em> and {@link #isGenerateDefaultLocations()} returns
|
||||
* {@code true}, default locations will be
|
||||
* {@link #generateDefaultLocations(Class) generated} for the specified
|
||||
* {@link Class class} and the configured
|
||||
* {@link #getResourceSuffix() resource suffix}; otherwise, the supplied
|
||||
* {@code locations} will be {@link #modifyLocations modified} if
|
||||
* necessary and returned.
|
||||
* If the supplied {@code locations} are {@code null} or <em>empty</em>
|
||||
* and {@link #isGenerateDefaultLocations()} returns {@code true},
|
||||
* default locations will be {@link #generateDefaultLocations(Class)
|
||||
* generated} (i.e., detected) for the specified {@link Class class}
|
||||
* and the configured {@linkplain #getResourceSuffixes() resource suffixes};
|
||||
* otherwise, the supplied {@code locations} will be
|
||||
* {@linkplain #modifyLocations modified} if necessary and returned.
|
||||
*
|
||||
* @param clazz the class with which the locations are associated: to be
|
||||
* used when generating default locations
|
||||
* @param locations the unmodified locations to use for loading the
|
||||
|
@ -173,45 +174,57 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
|
|||
/**
|
||||
* Generate the default classpath resource locations array based on the
|
||||
* supplied class.
|
||||
*
|
||||
* <p>For example, if the supplied class is {@code com.example.MyTest},
|
||||
* the generated locations will contain a single string with a value of
|
||||
* "classpath:com/example/MyTest{@code <suffix>}",
|
||||
* where {@code <suffix>} is the value of the
|
||||
* {@link #getResourceSuffix() resource suffix} string.
|
||||
* {@code "classpath:com/example/MyTest<suffix>"}, where {@code <suffix>}
|
||||
* is the value of the first configured
|
||||
* {@linkplain #getResourceSuffixes() resource suffix} for which the
|
||||
* generated location actually exists in the classpath.
|
||||
*
|
||||
* <p>As of Spring 3.1, the implementation of this method adheres to the
|
||||
* contract defined in the {@link SmartContextLoader} SPI. Specifically,
|
||||
* this method will <em>preemptively</em> verify that the generated default
|
||||
* location actually exists. If it does not exist, this method will log a
|
||||
* warning and return an empty array.
|
||||
*
|
||||
* <p>Subclasses can override this method to implement a different
|
||||
* <em>default location generation</em> strategy.
|
||||
*
|
||||
* @param clazz the class for which the default locations are to be generated
|
||||
* @return an array of default application context resource locations
|
||||
* @since 2.5
|
||||
* @see #getResourceSuffix()
|
||||
* @see #getResourceSuffixes()
|
||||
*/
|
||||
protected String[] generateDefaultLocations(Class<?> clazz) {
|
||||
Assert.notNull(clazz, "Class must not be null");
|
||||
String suffix = getResourceSuffix();
|
||||
Assert.hasText(suffix, "Resource suffix must not be empty");
|
||||
String resourcePath = ClassUtils.convertClassNameToResourcePath(clazz.getName()) + suffix;
|
||||
String prefixedResourcePath = ResourceUtils.CLASSPATH_URL_PREFIX + resourcePath;
|
||||
ClassPathResource classPathResource = new ClassPathResource(resourcePath);
|
||||
|
||||
if (classPathResource.exists()) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(String.format("Detected default resource location \"%s\" for test class [%s]",
|
||||
prefixedResourcePath, clazz.getName()));
|
||||
String[] suffixes = getResourceSuffixes();
|
||||
for (String suffix : suffixes) {
|
||||
Assert.hasText(suffix, "Resource suffix must not be empty");
|
||||
String resourcePath = ClassUtils.convertClassNameToResourcePath(clazz.getName()) + suffix;
|
||||
String prefixedResourcePath = ResourceUtils.CLASSPATH_URL_PREFIX + resourcePath;
|
||||
ClassPathResource classPathResource = new ClassPathResource(resourcePath);
|
||||
|
||||
if (classPathResource.exists()) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(String.format("Detected default resource location \"%s\" for test class [%s]",
|
||||
prefixedResourcePath, clazz.getName()));
|
||||
}
|
||||
return new String[] { prefixedResourcePath };
|
||||
}
|
||||
return new String[] { prefixedResourcePath };
|
||||
}
|
||||
else {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(String.format("Could not detect default resource locations for test class [%s]: "
|
||||
else if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("Did not detect default resource location for test class [%s]: "
|
||||
+ "%s does not exist", clazz.getName(), classPathResource));
|
||||
}
|
||||
return EMPTY_STRING_ARRAY;
|
||||
}
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(String.format("Could not detect default resource locations for test class [%s]: "
|
||||
+ "no resource found for suffixes %s.", clazz.getName(), ObjectUtils.nullSafeToString(suffixes)));
|
||||
}
|
||||
|
||||
return EMPTY_STRING_ARRAY;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -250,13 +263,36 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the suffix to append to {@link ApplicationContext} resource locations
|
||||
* when generating default locations.
|
||||
* <p>Must be implemented by subclasses.
|
||||
* @return the resource suffix; should not be {@code null} or empty
|
||||
* Get the suffix to append to {@link ApplicationContext} resource
|
||||
* locations when detecting default locations.
|
||||
*
|
||||
* <p>Subclasses must provide an implementation of this method that
|
||||
* returns a single suffix. Alternatively subclasses may provide a
|
||||
* <em>no-op</em> implementation of this method and override
|
||||
* {@link #getResourceSuffixes()} in order to provide multiple custom
|
||||
* suffixes.
|
||||
*
|
||||
* @return the resource suffix; never {@code null} or empty
|
||||
* @since 2.5
|
||||
* @see #generateDefaultLocations(Class)
|
||||
* @see #getResourceSuffixes()
|
||||
*/
|
||||
protected abstract String getResourceSuffix();
|
||||
|
||||
/**
|
||||
* Get the suffixes to append to {@link ApplicationContext} resource
|
||||
* locations when detecting default locations.
|
||||
*
|
||||
* <p>The default implementation simply wraps the value returned by
|
||||
* {@link #getResourceSuffix()} in a single-element array, but this
|
||||
* can be overridden by subclasses in order to support multiple suffixes.
|
||||
*
|
||||
* @return the resource suffixes; never {@code null} or empty
|
||||
* @since 4.1
|
||||
* @see #generateDefaultLocations(Class)
|
||||
*/
|
||||
protected String[] getResourceSuffixes() {
|
||||
return new String[] { getResourceSuffix() };
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,26 +35,33 @@ import org.springframework.util.ObjectUtils;
|
|||
* {@code AbstractDelegatingSmartContextLoader} serves as an abstract base class
|
||||
* for implementations of the {@link SmartContextLoader} SPI that delegate to a
|
||||
* set of <em>candidate</em> SmartContextLoaders (i.e., one that supports XML
|
||||
* configuration files and one that supports annotated classes) to determine which
|
||||
* context loader is appropriate for a given test class's configuration. Each
|
||||
* candidate is given a chance to {@link #processContextConfiguration process} the
|
||||
* configuration files or Groovy scripts and one that supports annotated classes)
|
||||
* to determine which context loader is appropriate for a given test class's
|
||||
* configuration. Each candidate is given a chance to
|
||||
* {@linkplain #processContextConfiguration process} the
|
||||
* {@link ContextConfigurationAttributes} for each class in the test class hierarchy
|
||||
* that is annotated with {@link ContextConfiguration @ContextConfiguration}, and
|
||||
* the candidate that supports the merged, processed configuration will be used to
|
||||
* actually {@link #loadContext load} the context.
|
||||
* actually {@linkplain #loadContext load} the context.
|
||||
*
|
||||
* <p>Any reference to an <em>XML-based loader</em> can be interpreted to mean
|
||||
* a context loader that supports only XML configuration files or one that
|
||||
* supports both XML configuration files and Groovy scripts simultaneously.
|
||||
*
|
||||
* <p>Placing an empty {@code @ContextConfiguration} annotation on a test class signals
|
||||
* that default resource locations (i.e., XML configuration files) or default
|
||||
* {@link org.springframework.context.annotation.Configuration configuration classes}
|
||||
* that default resource locations (e.g., XML configuration files or Groovy scripts)
|
||||
* or default
|
||||
* {@linkplain org.springframework.context.annotation.Configuration configuration classes}
|
||||
* should be detected. Furthermore, if a specific {@link ContextLoader} or
|
||||
* {@link SmartContextLoader} is not explicitly declared via
|
||||
* {@code @ContextConfiguration}, a concrete subclass of
|
||||
* {@code AbstractDelegatingSmartContextLoader} will be used as the default loader,
|
||||
* thus providing automatic support for either XML configuration files or annotated
|
||||
* classes, but not both simultaneously.
|
||||
* thus providing automatic support for either path-based resource locations
|
||||
* (e.g., XML configuration files and Groovy scripts) 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
|
||||
* <p>As of Spring 3.2, a test class may optionally declare neither path-based
|
||||
* resource locations 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 in an exception.
|
||||
|
@ -69,7 +76,8 @@ public abstract class AbstractDelegatingSmartContextLoader implements SmartConte
|
|||
|
||||
|
||||
/**
|
||||
* Get the delegate {@code SmartContextLoader} that supports XML configuration files.
|
||||
* Get the delegate {@code SmartContextLoader} that supports XML configuration
|
||||
* files and/or Groovy scripts.
|
||||
*/
|
||||
protected abstract SmartContextLoader getXmlLoader();
|
||||
|
||||
|
@ -115,9 +123,9 @@ public abstract class AbstractDelegatingSmartContextLoader implements SmartConte
|
|||
* Delegates to candidate {@code SmartContextLoaders} to process the supplied
|
||||
* {@link ContextConfigurationAttributes}.
|
||||
* <p>Delegation is based on explicit knowledge of the implementations of the
|
||||
* default loaders for {@link #getXmlLoader() XML configuration files} and
|
||||
* {@link #getAnnotationConfigLoader() annotated classes}. Specifically, the
|
||||
* delegation algorithm is as follows:
|
||||
* default loaders for {@linkplain #getXmlLoader() XML configuration files and
|
||||
* Groovy scripts} and {@linkplain #getAnnotationConfigLoader() annotated classes}.
|
||||
* Specifically, the delegation algorithm is as follows:
|
||||
* <ul>
|
||||
* <li>If the resource locations or annotated classes in the supplied
|
||||
* {@code ContextConfigurationAttributes} are not empty, the appropriate
|
||||
|
@ -220,9 +228,9 @@ public abstract class AbstractDelegatingSmartContextLoader implements SmartConte
|
|||
* Delegates to an appropriate candidate {@code SmartContextLoader} to load
|
||||
* an {@link ApplicationContext}.
|
||||
* <p>Delegation is based on explicit knowledge of the implementations of the
|
||||
* default loaders for {@link #getXmlLoader() XML configuration files} and
|
||||
* {@link #getAnnotationConfigLoader() annotated classes}. Specifically, the
|
||||
* delegation algorithm is as follows:
|
||||
* default loaders for {@linkplain #getXmlLoader() XML configuration files and
|
||||
* Groovy scripts} and {@linkplain #getAnnotationConfigLoader() annotated classes}.
|
||||
* Specifically, the delegation algorithm is as follows:
|
||||
* <ul>
|
||||
* <li>If the resource locations in the supplied {@code MergedContextConfiguration}
|
||||
* are not empty and the annotated classes are empty,
|
||||
|
|
|
@ -49,6 +49,8 @@ import org.springframework.util.ObjectUtils;
|
|||
* @see #processContextConfiguration(ContextConfigurationAttributes)
|
||||
* @see #detectDefaultConfigurationClasses(Class)
|
||||
* @see #loadBeanDefinitions(GenericApplicationContext, MergedContextConfiguration)
|
||||
* @see GenericXmlContextLoader
|
||||
* @see GenericGroovyXmlContextLoader
|
||||
*/
|
||||
public class AnnotationConfigContextLoader extends AbstractGenericContextLoader {
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,25 +16,55 @@
|
|||
|
||||
package org.springframework.test.context.support;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.test.context.SmartContextLoader;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@code DelegatingSmartContextLoader} is a concrete implementation of
|
||||
* {@link AbstractDelegatingSmartContextLoader} that delegates to a
|
||||
* {@link GenericXmlContextLoader} and an {@link AnnotationConfigContextLoader}.
|
||||
* {@link GenericXmlContextLoader} (or a {@link GenericGroovyXmlContextLoader} if Groovy
|
||||
* is present in the classpath) and an {@link AnnotationConfigContextLoader}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 3.1
|
||||
* @see SmartContextLoader
|
||||
* @see AbstractDelegatingSmartContextLoader
|
||||
* @see GenericXmlContextLoader
|
||||
* @see GenericGroovyXmlContextLoader
|
||||
* @see AnnotationConfigContextLoader
|
||||
*/
|
||||
public class DelegatingSmartContextLoader extends AbstractDelegatingSmartContextLoader {
|
||||
|
||||
private final SmartContextLoader xmlLoader = new GenericXmlContextLoader();
|
||||
private final SmartContextLoader annotationConfigLoader = new AnnotationConfigContextLoader();
|
||||
private static final String GROOVY_XML_CONTEXT_LOADER_CLASS_NAME = "org.springframework.test.context.support.GenericGroovyXmlContextLoader";
|
||||
|
||||
private static final boolean groovyPresent = ClassUtils.isPresent("groovy.lang.Closure",
|
||||
DelegatingSmartContextLoader.class.getClassLoader())
|
||||
&& ClassUtils.isPresent(GROOVY_XML_CONTEXT_LOADER_CLASS_NAME,
|
||||
DelegatingSmartContextLoader.class.getClassLoader());
|
||||
|
||||
private final SmartContextLoader xmlLoader;
|
||||
private final SmartContextLoader annotationConfigLoader;
|
||||
|
||||
|
||||
public DelegatingSmartContextLoader() {
|
||||
if (groovyPresent) {
|
||||
try {
|
||||
Class<?> loaderClass = ClassUtils.forName(GROOVY_XML_CONTEXT_LOADER_CLASS_NAME,
|
||||
DelegatingSmartContextLoader.class.getClassLoader());
|
||||
this.xmlLoader = (SmartContextLoader) BeanUtils.instantiateClass(loaderClass);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new IllegalStateException("Failed to enable support for Groovy scripts; "
|
||||
+ "could not load class: " + GROOVY_XML_CONTEXT_LOADER_CLASS_NAME, ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.xmlLoader = new GenericXmlContextLoader();
|
||||
}
|
||||
|
||||
this.annotationConfigLoader = new AnnotationConfigContextLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SmartContextLoader getXmlLoader() {
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.support;
|
||||
|
||||
import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReader;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
|
||||
/**
|
||||
* Concrete implementation of {@link AbstractGenericContextLoader} that reads
|
||||
* bean definitions from Groovy scripts <em>and</em> XML configuration files.
|
||||
*
|
||||
* <p>Default resource locations are detected using the suffixes
|
||||
* {@code "-context.xml"} and {@code "Context.groovy"}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
* @see GroovyBeanDefinitionReader
|
||||
* @see GenericXmlContextLoader
|
||||
* @see AnnotationConfigContextLoader
|
||||
*/
|
||||
public class GenericGroovyXmlContextLoader extends GenericXmlContextLoader {
|
||||
|
||||
/**
|
||||
* Create a new {@link GroovyBeanDefinitionReader}.
|
||||
* @return a new {@code GroovyBeanDefinitionReader}
|
||||
*/
|
||||
@Override
|
||||
protected BeanDefinitionReader createBeanDefinitionReader(final GenericApplicationContext context) {
|
||||
return new GroovyBeanDefinitionReader(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code "-context.xml" and "Context.groovy"} in order to
|
||||
* support detection of a default XML config file or Groovy script.
|
||||
*/
|
||||
@Override
|
||||
protected String[] getResourceSuffixes() {
|
||||
return new String[] { super.getResourceSuffix(), "Context.groovy" };
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code GenericGroovyXmlContextLoader} supports both Groovy and XML
|
||||
* resource types for detection of defaults. Consequently, this method
|
||||
* is not supported.
|
||||
* @see #getResourceSuffixes()
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
@Override
|
||||
protected String getResourceSuffix() {
|
||||
throw new UnsupportedOperationException(
|
||||
"GenericGroovyXmlContextLoader does not support the getResourceSuffix() method");
|
||||
}
|
||||
|
||||
}
|
|
@ -26,23 +26,29 @@ import org.springframework.util.ObjectUtils;
|
|||
* Concrete implementation of {@link AbstractGenericContextLoader} that reads
|
||||
* bean definitions from XML resources.
|
||||
*
|
||||
* <p>Default resource locations are detected using the suffix
|
||||
* {@code "-context.xml"}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 2.5
|
||||
* @see XmlBeanDefinitionReader
|
||||
* @see GenericGroovyXmlContextLoader
|
||||
* @see AnnotationConfigContextLoader
|
||||
*/
|
||||
public class GenericXmlContextLoader extends AbstractGenericContextLoader {
|
||||
|
||||
/**
|
||||
* Create a new {@link XmlBeanDefinitionReader}.
|
||||
* @return a new XmlBeanDefinitionReader
|
||||
* @see XmlBeanDefinitionReader
|
||||
* @return a new {@code XmlBeanDefinitionReader}
|
||||
*/
|
||||
@Override
|
||||
protected BeanDefinitionReader createBeanDefinitionReader(final GenericApplicationContext context) {
|
||||
protected BeanDefinitionReader createBeanDefinitionReader(GenericApplicationContext context) {
|
||||
return new XmlBeanDefinitionReader(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns "{@code -context.xml}".
|
||||
* Returns {@code "-context.xml"} in order to support detection of a
|
||||
* default XML config file.
|
||||
*/
|
||||
@Override
|
||||
protected String getResourceSuffix() {
|
||||
|
|
|
@ -50,6 +50,8 @@ import org.springframework.web.context.support.GenericWebApplicationContext;
|
|||
* @see #processContextConfiguration(ContextConfigurationAttributes)
|
||||
* @see #detectDefaultConfigurationClasses(Class)
|
||||
* @see #loadBeanDefinitions(GenericWebApplicationContext, WebMergedContextConfiguration)
|
||||
* @see GenericXmlWebContextLoader
|
||||
* @see GenericGroovyXmlWebContextLoader
|
||||
*/
|
||||
public class AnnotationConfigWebContextLoader extends AbstractGenericWebContextLoader {
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.web;
|
||||
|
||||
import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader;
|
||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||
|
||||
/**
|
||||
* Concrete implementation of {@link AbstractGenericWebContextLoader} that loads
|
||||
* bean definitions from Groovy scripts <em>and</em> XML configuration files.
|
||||
*
|
||||
* <p>Default resource locations are detected using the suffixes
|
||||
* {@code "-context.xml"} and {@code "Context.groovy"}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
* @see GroovyBeanDefinitionReader
|
||||
* @see GenericXmlWebContextLoader
|
||||
* @see AnnotationConfigWebContextLoader
|
||||
*/
|
||||
public class GenericGroovyXmlWebContextLoader extends GenericXmlWebContextLoader {
|
||||
|
||||
/**
|
||||
* Loads bean definitions using a {@link GroovyBeanDefinitionReader}.
|
||||
* @see AbstractGenericWebContextLoader#loadBeanDefinitions
|
||||
*/
|
||||
@Override
|
||||
protected void loadBeanDefinitions(GenericWebApplicationContext context,
|
||||
WebMergedContextConfiguration webMergedConfig) {
|
||||
new GroovyBeanDefinitionReader(context).loadBeanDefinitions(webMergedConfig.getLocations());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code "-context.xml" and "Context.groovy"} in order to
|
||||
* support detection of a default XML config file or Groovy script.
|
||||
*/
|
||||
@Override
|
||||
protected String[] getResourceSuffixes() {
|
||||
return new String[] { super.getResourceSuffix(), "Context.groovy" };
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code GenericGroovyXmlWebContextLoader} supports both Groovy and XML
|
||||
* resource types for detection of defaults. Consequently, this method
|
||||
* is not supported.
|
||||
* @see #getResourceSuffixes()
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
@Override
|
||||
protected String getResourceSuffix() {
|
||||
throw new UnsupportedOperationException(
|
||||
"GenericGroovyXmlWebContextLoader does not support the getResourceSuffix() method");
|
||||
}
|
||||
|
||||
}
|
|
@ -25,8 +25,13 @@ import org.springframework.web.context.support.GenericWebApplicationContext;
|
|||
* Concrete implementation of {@link AbstractGenericWebContextLoader} that loads
|
||||
* bean definitions from XML resources.
|
||||
*
|
||||
* <p>Default resource locations are detected using the suffix
|
||||
* {@code "-context.xml"}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
* @see GenericGroovyXmlWebContextLoader
|
||||
* @see AnnotationConfigWebContextLoader
|
||||
*/
|
||||
public class GenericXmlWebContextLoader extends AbstractGenericWebContextLoader {
|
||||
|
||||
|
@ -41,7 +46,8 @@ public class GenericXmlWebContextLoader extends AbstractGenericWebContextLoader
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns "{@code -context.xml}".
|
||||
* Returns {@code "-context.xml"} in order to support detection of a
|
||||
* default XML config file.
|
||||
*/
|
||||
@Override
|
||||
protected String getResourceSuffix() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,13 +16,16 @@
|
|||
|
||||
package org.springframework.test.context.web;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.test.context.SmartContextLoader;
|
||||
import org.springframework.test.context.support.AbstractDelegatingSmartContextLoader;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@code WebDelegatingSmartContextLoader} is a concrete implementation of
|
||||
* {@link AbstractDelegatingSmartContextLoader} that delegates to a
|
||||
* {@link GenericXmlWebContextLoader} and an {@link AnnotationConfigWebContextLoader}.
|
||||
* {@link GenericXmlWebContextLoader} (or a {@link GenericGroovyXmlWebContextLoader} if
|
||||
* Groovy is present on the classpath) and an {@link AnnotationConfigWebContextLoader}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 3.2
|
||||
|
@ -33,9 +36,35 @@ import org.springframework.test.context.support.AbstractDelegatingSmartContextLo
|
|||
*/
|
||||
public class WebDelegatingSmartContextLoader extends AbstractDelegatingSmartContextLoader {
|
||||
|
||||
private final SmartContextLoader xmlLoader = new GenericXmlWebContextLoader();
|
||||
private final SmartContextLoader annotationConfigLoader = new AnnotationConfigWebContextLoader();
|
||||
private static final String GROOVY_XML_WEB_CONTEXT_LOADER_CLASS_NAME = "org.springframework.test.context.web.GenericGroovyXmlWebContextLoader";
|
||||
|
||||
private static final boolean groovyPresent = ClassUtils.isPresent("groovy.lang.Closure",
|
||||
WebDelegatingSmartContextLoader.class.getClassLoader())
|
||||
&& ClassUtils.isPresent(GROOVY_XML_WEB_CONTEXT_LOADER_CLASS_NAME,
|
||||
WebDelegatingSmartContextLoader.class.getClassLoader());
|
||||
|
||||
private final SmartContextLoader xmlLoader;
|
||||
private final SmartContextLoader annotationConfigLoader;
|
||||
|
||||
|
||||
public WebDelegatingSmartContextLoader() {
|
||||
if (groovyPresent) {
|
||||
try {
|
||||
Class<?> loaderClass = ClassUtils.forName(GROOVY_XML_WEB_CONTEXT_LOADER_CLASS_NAME,
|
||||
WebDelegatingSmartContextLoader.class.getClassLoader());
|
||||
this.xmlLoader = (SmartContextLoader) BeanUtils.instantiateClass(loaderClass);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new IllegalStateException("Failed to enable support for Groovy scripts; "
|
||||
+ "could not load class: " + GROOVY_XML_WEB_CONTEXT_LOADER_CLASS_NAME, ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.xmlLoader = new GenericXmlWebContextLoader();
|
||||
}
|
||||
|
||||
this.annotationConfigLoader = new AnnotationConfigWebContextLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SmartContextLoader getXmlLoader() {
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.groovy;
|
||||
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
/**
|
||||
* Extension of {@link GroovySpringContextTests} that declares a Groovy
|
||||
* script using an absolute path.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
* @see GroovySpringContextTests
|
||||
* @see RelativePathGroovySpringContextTests
|
||||
*/
|
||||
@ContextConfiguration(locations = "/org/springframework/test/context/groovy/context.groovy", inheritLocations = false)
|
||||
public class AbsolutePathGroovySpringContextTests extends GroovySpringContextTests {
|
||||
|
||||
/* all tests are in the superclass */
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.groovy;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.tests.sample.beans.Employee;
|
||||
import org.springframework.tests.sample.beans.Pet;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Integration test class that verifies proper detection of a default
|
||||
* Groovy script (as opposed to a default XML config file).
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
* @see DefaultScriptDetectionGroovySpringContextTestsContext
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
// Config loaded from DefaultScriptDetectionGroovySpringContextTestsContext.groovy
|
||||
@ContextConfiguration
|
||||
public class DefaultScriptDetectionGroovySpringContextTests {
|
||||
|
||||
@Autowired
|
||||
private Employee employee;
|
||||
|
||||
@Autowired
|
||||
private Pet pet;
|
||||
|
||||
@Autowired
|
||||
protected String foo;
|
||||
|
||||
|
||||
@Test
|
||||
public final void verifyAnnotationAutowiredFields() {
|
||||
assertNotNull("The employee field should have been autowired.", this.employee);
|
||||
assertEquals("Dilbert", this.employee.getName());
|
||||
|
||||
assertNotNull("The pet field should have been autowired.", this.pet);
|
||||
assertEquals("Dogbert", this.pet.getName());
|
||||
|
||||
assertEquals("The foo field should have been autowired.", "Foo", this.foo);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.groovy
|
||||
|
||||
import org.springframework.tests.sample.beans.Employee;
|
||||
import org.springframework.tests.sample.beans.Pet;
|
||||
|
||||
/**
|
||||
* Groovy script for defining Spring beans for integration tests.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
beans {
|
||||
|
||||
foo String, 'Foo'
|
||||
bar String, 'Bar'
|
||||
|
||||
employee(Employee) {
|
||||
name = "Dilbert"
|
||||
age = 42
|
||||
company = "???"
|
||||
}
|
||||
|
||||
pet(Pet, 'Dogbert')
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?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>
|
||||
|
||||
</beans>
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.groovy;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Integration test class that verifies proper detection of a default
|
||||
* XML config file even though a suitable Groovy script exists.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class DefaultScriptDetectionXmlSupersedesGroovySpringContextTests {
|
||||
|
||||
@Autowired
|
||||
protected String foo;
|
||||
|
||||
|
||||
@Test
|
||||
public final void foo() {
|
||||
assertEquals("The foo field should have been autowired.", "Foo", this.foo);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.groovy
|
||||
|
||||
/**
|
||||
* This is intentionally an empty config file, since the XML file should
|
||||
* be picked up as the default before a Groovy script.
|
||||
*
|
||||
* <p>See: {@code DefaultScriptDetectionXmlSupersedesGroovySpringContextTests-context.xml}
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
beans {
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.groovy;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.GenericGroovyApplicationContext;
|
||||
import org.springframework.tests.sample.beans.Employee;
|
||||
import org.springframework.tests.sample.beans.Pet;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Simple integration test to verify the expected functionality of
|
||||
* {@link GenericGroovyApplicationContext}, thereby validating the proper
|
||||
* syntax and configuration of {@code "context.groovy"} without using the
|
||||
* Spring TestContext Framework.
|
||||
*
|
||||
* <p>In other words, this test class serves merely as a <em>control group</em>
|
||||
* to ensure that there is nothing wrong with the Groovy script used by
|
||||
* other tests in this package.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
public class GroovyControlGroupTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
public void verifyScriptUsingGenericGroovyApplicationContext() {
|
||||
ApplicationContext ctx = new GenericGroovyApplicationContext(getClass(), "context.groovy");
|
||||
|
||||
String foo = ctx.getBean("foo", String.class);
|
||||
assertEquals("Foo", foo);
|
||||
|
||||
String bar = ctx.getBean("bar", String.class);
|
||||
assertEquals("Bar", bar);
|
||||
|
||||
Pet pet = ctx.getBean(Pet.class);
|
||||
assertNotNull("pet", pet);
|
||||
assertEquals("Dogbert", pet.getName());
|
||||
|
||||
Employee employee = ctx.getBean(Employee.class);
|
||||
assertNotNull("employee", employee);
|
||||
assertEquals("Dilbert", employee.getName());
|
||||
assertEquals("???", employee.getCompany());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.groovy;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.tests.sample.beans.Employee;
|
||||
import org.springframework.tests.sample.beans.Pet;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Integration tests for loading an {@code ApplicationContext} from a
|
||||
* Groovy script with the TestContext framework.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("context.groovy")
|
||||
public class GroovySpringContextTests implements BeanNameAware, InitializingBean {
|
||||
|
||||
private boolean beanInitialized = false;
|
||||
|
||||
private String beanName = "replace me with [" + getClass().getName() + "]";
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private Employee employee;
|
||||
|
||||
@Autowired
|
||||
private Pet pet;
|
||||
|
||||
@Autowired(required = false)
|
||||
protected Long nonrequiredLong;
|
||||
|
||||
@Resource
|
||||
protected String foo;
|
||||
|
||||
protected String bar;
|
||||
|
||||
|
||||
@Autowired
|
||||
protected final void setEmployee(final Employee employee) {
|
||||
this.employee = employee;
|
||||
}
|
||||
|
||||
@Resource
|
||||
protected final void setBar(final String bar) {
|
||||
this.bar = bar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setBeanName(final String beanName) {
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void afterPropertiesSet() throws Exception {
|
||||
this.beanInitialized = true;
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void verifyBeanInitialized() {
|
||||
assertTrue("This test bean should have been initialized due to InitializingBean semantics.",
|
||||
this.beanInitialized);
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void verifyBeanNameSet() {
|
||||
assertEquals("The bean name of this test instance should have been set to the fully qualified class name "
|
||||
+ "due to BeanNameAware semantics.", getClass().getName(), this.beanName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void verifyAnnotationAutowiredFields() {
|
||||
assertNull("The nonrequiredLong property should NOT have been autowired.", this.nonrequiredLong);
|
||||
assertNotNull("The application context should have been autowired.", this.applicationContext);
|
||||
assertNotNull("The pet field should have been autowired.", this.pet);
|
||||
assertEquals("Dogbert", this.pet.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void verifyAnnotationAutowiredMethods() {
|
||||
assertNotNull("The employee setter method should have been autowired.", this.employee);
|
||||
assertEquals("Dilbert", this.employee.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void verifyResourceAnnotationWiredFields() {
|
||||
assertEquals("The foo field should have been wired via @Resource.", "Foo", this.foo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void verifyResourceAnnotationWiredMethods() {
|
||||
assertEquals("The bar method should have been wired via @Resource.", "Bar", this.bar);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.groovy;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.tests.sample.beans.Employee;
|
||||
import org.springframework.tests.sample.beans.Pet;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Integration test class that verifies proper support for mixing XML
|
||||
* configuration files and Groovy scripts to load an {@code ApplicationContext}
|
||||
* using the TestContext framework.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration({ "contextA.groovy", "contextB.xml" })
|
||||
public class MixedXmlAndGroovySpringContextTests {
|
||||
|
||||
@Autowired
|
||||
private Employee employee;
|
||||
|
||||
@Autowired
|
||||
private Pet pet;
|
||||
|
||||
@Autowired
|
||||
protected String foo;
|
||||
|
||||
@Autowired
|
||||
protected String bar;
|
||||
|
||||
|
||||
@Test
|
||||
public final void verifyAnnotationAutowiredFields() {
|
||||
assertNotNull("The employee field should have been autowired.", this.employee);
|
||||
assertEquals("Dilbert", this.employee.getName());
|
||||
|
||||
assertNotNull("The pet field should have been autowired.", this.pet);
|
||||
assertEquals("Dogbert", this.pet.getName());
|
||||
|
||||
assertEquals("The foo field should have been autowired.", "Groovy Foo", this.foo);
|
||||
assertEquals("The bar field should have been autowired.", "XML Bar", this.bar);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.groovy;
|
||||
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
/**
|
||||
* Extension of {@link GroovySpringContextTests} that declares a Groovy
|
||||
* script using a relative path.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
* @see GroovySpringContextTests
|
||||
* @see AbsolutePathGroovySpringContextTests
|
||||
*/
|
||||
@ContextConfiguration(locations = "../groovy/context.groovy", inheritLocations = false)
|
||||
public class RelativePathGroovySpringContextTests extends GroovySpringContextTests {
|
||||
|
||||
/* all tests are in the superclass */
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.groovy
|
||||
|
||||
import org.springframework.tests.sample.beans.Employee;
|
||||
import org.springframework.tests.sample.beans.Pet;
|
||||
|
||||
/**
|
||||
* Groovy script for defining Spring beans for integration tests.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
beans {
|
||||
|
||||
foo String, 'Foo'
|
||||
bar String, 'Bar'
|
||||
|
||||
employee(Employee) {
|
||||
name = "Dilbert"
|
||||
age = 42
|
||||
company = "???"
|
||||
}
|
||||
|
||||
pet(Pet, 'Dogbert')
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.groovy
|
||||
|
||||
/**
|
||||
* Groovy script for defining Spring beans for integration tests.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
*/
|
||||
beans {
|
||||
|
||||
foo String, 'Groovy Foo'
|
||||
bar String, 'Groovy Bar'
|
||||
|
||||
}
|
|
@ -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="employee" class="org.springframework.tests.sample.beans.Employee">
|
||||
<property name="name" value="Dilbert" />
|
||||
<property name="age" value="42" />
|
||||
<property name="company" value="???" />
|
||||
</bean>
|
||||
|
||||
<bean id="pet" class="org.springframework.tests.sample.beans.Pet">
|
||||
<constructor-arg value="Dogbert" />
|
||||
</bean>
|
||||
|
||||
<bean id="bar" class="java.lang.String">
|
||||
<constructor-arg value="XML Bar" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.web;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
/**
|
||||
* @author Sam Brannen
|
||||
* @since 4.1
|
||||
* @see BasicXmlWacTests
|
||||
*/
|
||||
// Config loaded from BasicGroovyWacTestsContext.groovy
|
||||
@ContextConfiguration
|
||||
public class BasicGroovyWacTests extends AbstractBasicWacTests {
|
||||
|
||||
@Test
|
||||
public void groovyFooAutowired() {
|
||||
assertEquals("Groovy Foo", foo);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package org.springframework.test.context.web
|
||||
|
||||
beans { foo String, 'Groovy Foo' }
|
|
@ -1,6 +1,6 @@
|
|||
log4j.appender.console=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.console.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.console.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%c] - %m%n
|
||||
log4j.appender.console.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%-5p] [%c] - %m%n
|
||||
|
||||
log4j.appender.file=org.apache.log4j.FileAppender
|
||||
log4j.appender.file.file=build/spring-test.log
|
||||
|
@ -16,6 +16,7 @@ log4j.logger.org.springframework.test.context.transaction.TransactionalTestExecu
|
|||
log4j.logger.org.springframework.test.context.web=WARN
|
||||
log4j.logger.org.springframework.test.context=WARN
|
||||
|
||||
#log4j.logger.org.springframework.test.context.support=INFO
|
||||
#log4j.logger.org.springframework.test.context.support.DelegatingSmartContextLoader=INFO
|
||||
#log4j.logger.org.springframework.test.context.support.AbstractGenericContextLoader=INFO
|
||||
#log4j.logger.org.springframework.test.context.support.AnnotationConfigContextLoader=INFO
|
||||
|
|
Loading…
Reference in New Issue