Merge from sbrannen/SPR-11233

* SPR-11233:
  Support Groovy scripts in the TCF
This commit is contained in:
Sam Brannen
2014-07-24 17:09:19 +02:00
28 changed files with 1011 additions and 111 deletions

View File

@@ -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")

View File

@@ -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
* &quot;base-context.xml&quot; <strong>and</strong>
* &quot;extended-context.xml&quot;, in that order. Beans defined in
* &quot;extended-context.xml&quot; may therefore override those defined in
* &quot;base-context.xml&quot;.
* {@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">
* &#064;ContextConfiguration(&quot;base-context.xml&quot;)
* &#064;ContextConfiguration("base-context.xml")
* public class BaseTest {
* // ...
* }
*
* &#064;ContextConfiguration(&quot;extended-context.xml&quot;)
* &#064;ContextConfiguration("extended-context.xml")
* public class ExtendedTest extends BaseTest {
* // ...
* }
@@ -281,16 +285,13 @@ public @interface ContextConfiguration {
* {@link org.springframework.test.context.web.WebAppConfiguration
* &#064;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
*/

View File

@@ -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
* &quot;classpath:com/example/MyTest{@code <suffix>}&quot;,
* 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() };
}
}

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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() {

View File

@@ -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");
}
}

View File

@@ -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 &quot;{@code -context.xml}&quot;.
* Returns {@code "-context.xml"} in order to support detection of a
* default XML config file.
*/
@Override
protected String getResourceSuffix() {

View File

@@ -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 {

View File

@@ -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");
}
}

View File

@@ -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 &quot;{@code -context.xml}&quot;.
* Returns {@code "-context.xml"} in order to support detection of a
* default XML config file.
*/
@Override
protected String getResourceSuffix() {

View File

@@ -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() {

View File

@@ -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 */
}

View File

@@ -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);
}
}

View File

@@ -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')
}

View File

@@ -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>

View File

@@ -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);
}
}

View File

@@ -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 {
}

View File

@@ -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());
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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 */
}

View File

@@ -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')
}

View File

@@ -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'
}

View File

@@ -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>

View File

@@ -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);
}
}

View File

@@ -0,0 +1,3 @@
package org.springframework.test.context.web
beans { foo String, 'Groovy Foo' }

View File

@@ -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