[SPR-5916] ContextLoader class is now inherited from class hierarchy if not specified explicitly via @ContextConfiguration's loader attribute on the current test class.
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@1561 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
parent
b8811bb720
commit
2d1d61cb0f
|
|
@ -87,6 +87,10 @@ public @interface ContextConfiguration {
|
|||
/**
|
||||
* The type of {@link ContextLoader} to use for loading an
|
||||
* {@link org.springframework.context.ApplicationContext ApplicationContext}.
|
||||
* <p>If not specified, the loader will be inherited from the first superclass
|
||||
* which is annotated with <code>@ContextConfiguration</code> and specifies
|
||||
* an explicit loader. If no class in the hierarchy specifies an explicit
|
||||
* loader, a default loader will be used instead.
|
||||
*/
|
||||
Class<? extends ContextLoader> loader() default ContextLoader.class;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
|
|
@ -95,7 +95,6 @@ public class TestContext extends AttributeAccessorSupport {
|
|||
* @param defaultContextLoaderClassName the name of the default
|
||||
* <code>ContextLoader</code> class to use (may be <code>null</code>)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
TestContext(Class<?> testClass, ContextCache contextCache, String defaultContextLoaderClassName) {
|
||||
Assert.notNull(testClass, "Test class must not be null");
|
||||
Assert.notNull(contextCache, "ContextCache must not be null");
|
||||
|
|
@ -119,23 +118,8 @@ public class TestContext extends AttributeAccessorSupport {
|
|||
+ "]");
|
||||
}
|
||||
|
||||
Class<? extends ContextLoader> contextLoaderClass = contextConfiguration.loader();
|
||||
if (ContextLoader.class.equals(contextLoaderClass)) {
|
||||
try {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Using default ContextLoader class [" + defaultContextLoaderClassName
|
||||
+ "] for @ContextConfiguration [" + contextConfiguration + "] and class [" + testClass
|
||||
+ "]");
|
||||
}
|
||||
contextLoaderClass = (Class<? extends ContextLoader>) getClass().getClassLoader().loadClass(
|
||||
defaultContextLoaderClassName);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
throw new IllegalStateException("Could not load default ContextLoader class ["
|
||||
+ defaultContextLoaderClassName + "]. Specify @ContextConfiguration's 'loader' "
|
||||
+ "attribute or make the default loader class available.");
|
||||
}
|
||||
}
|
||||
Class<? extends ContextLoader> contextLoaderClass = retrieveContextLoaderClass(testClass,
|
||||
defaultContextLoaderClassName);
|
||||
contextLoader = (ContextLoader) BeanUtils.instantiateClass(contextLoaderClass);
|
||||
locations = retrieveContextLocations(contextLoader, testClass);
|
||||
}
|
||||
|
|
@ -146,6 +130,80 @@ public class TestContext extends AttributeAccessorSupport {
|
|||
this.locations = locations;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Retrieve the {@link ContextLoader} {@link Class} to use for the supplied
|
||||
* {@link Class test class}.
|
||||
* <ol>
|
||||
* <li>If the {@link ContextConfiguration#loader() loader} attribute of
|
||||
* {@link ContextConfiguration @ContextConfiguration} is configured
|
||||
* with an explicit class, that class will be returned.</li>
|
||||
* <li>If a <code>loader</code> class is not specified, the class hierarchy
|
||||
* will be traversed to find a parent class annotated with
|
||||
* <code>@ContextConfiguration</code>; go to step #1.</li>
|
||||
* </ol>
|
||||
* <p>
|
||||
* If no explicit <code>loader</code> class is found after traversing the
|
||||
* class hierarchy, an attempt will be made to load and return the class
|
||||
* with the supplied <code>defaultContextLoaderClassName</code>.
|
||||
*
|
||||
* @param clazz the class for which to retrieve <code>ContextLoader</code>
|
||||
* class; must not be <code>null</code>
|
||||
* @param defaultContextLoaderClassName the name of the default
|
||||
* <code>ContextLoader</code> class to use; must not be <code>null</code> or
|
||||
* empty
|
||||
* @return the <code>ContextLoader</code> class to use for the specified
|
||||
* class
|
||||
* @throws IllegalArgumentException if {@link ContextConfiguration
|
||||
* @ContextConfiguration} is not <em>present</em> on the supplied class
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private Class<? extends ContextLoader> retrieveContextLoaderClass(Class<?> clazz,
|
||||
String defaultContextLoaderClassName) {
|
||||
Assert.notNull(clazz, "Class must not be null");
|
||||
Assert.hasText(defaultContextLoaderClassName, "Default ContextLoader class name must not be null or empty");
|
||||
|
||||
Class<ContextConfiguration> annotationType = ContextConfiguration.class;
|
||||
Class<?> declaringClass = AnnotationUtils.findAnnotationDeclaringClass(annotationType, clazz);
|
||||
Assert.notNull(declaringClass, "Could not find an 'annotation declaring class' for annotation type ["
|
||||
+ annotationType + "] and class [" + clazz + "]");
|
||||
|
||||
while (declaringClass != null) {
|
||||
ContextConfiguration contextConfiguration = declaringClass.getAnnotation(annotationType);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Processing ContextLoader for @ContextConfiguration [" + contextConfiguration
|
||||
+ "] and declaring class [" + declaringClass + "]");
|
||||
}
|
||||
|
||||
Class<? extends ContextLoader> contextLoaderClass = contextConfiguration.loader();
|
||||
if (!ContextLoader.class.equals(contextLoaderClass)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found explicit ContextLoader [" + contextLoaderClass
|
||||
+ "] for @ContextConfiguration [" + contextConfiguration + "] and declaring class ["
|
||||
+ declaringClass + "]");
|
||||
}
|
||||
return contextLoaderClass;
|
||||
}
|
||||
|
||||
declaringClass = AnnotationUtils.findAnnotationDeclaringClass(annotationType,
|
||||
declaringClass.getSuperclass());
|
||||
}
|
||||
|
||||
try {
|
||||
ContextConfiguration contextConfiguration = clazz.getAnnotation(ContextConfiguration.class);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Using default ContextLoader class [" + defaultContextLoaderClassName
|
||||
+ "] for @ContextConfiguration [" + contextConfiguration + "] and class [" + clazz + "]");
|
||||
}
|
||||
return (Class<? extends ContextLoader>) getClass().getClassLoader().loadClass(defaultContextLoaderClassName);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
throw new IllegalStateException("Could not load default ContextLoader class ["
|
||||
+ defaultContextLoaderClassName + "]. Specify @ContextConfiguration's 'loader' "
|
||||
+ "attribute or make the default loader class available.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve {@link ApplicationContext} resource locations for the supplied
|
||||
* {@link Class class}, using the supplied {@link ContextLoader} to
|
||||
|
|
@ -157,10 +215,10 @@ public class TestContext extends AttributeAccessorSupport {
|
|||
* @ContextConfiguration} will be taken into consideration.
|
||||
* Specifically, if the <code>inheritLocations</code> flag is set to
|
||||
* <code>true</code>, locations defined in the annotated class will be
|
||||
* appended to the locations defined in superclasses. @param
|
||||
* contextLoader the ContextLoader to use for processing the locations (must
|
||||
* not be <code>null</code>)
|
||||
* appended to the locations defined in superclasses.
|
||||
*
|
||||
* @param contextLoader the ContextLoader to use for processing the
|
||||
* locations (must not be <code>null</code>)
|
||||
* @param clazz the class for which to retrieve the resource locations (must
|
||||
* not be <code>null</code>)
|
||||
* @return the list of ApplicationContext resource locations for the
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
dog.(class)=org.springframework.beans.Pet
|
||||
dog.$0=Fido
|
||||
|
||||
testString2.(class)=java.lang.String
|
||||
testString2.$0=Test String #2
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.configuration;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.Pet;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.ContextLoader;
|
||||
import org.springframework.test.context.junit4.PropertiesBasedSpringJUnit4ClassRunnerAppCtxTests;
|
||||
|
||||
/**
|
||||
* Integration tests which verify that the same custom {@link ContextLoader} can
|
||||
* be used at all levels within a test class hierarchy when the
|
||||
* <code>loader</code> is <i>inherited</i> (i.e., not explicitly declared) via
|
||||
* {@link ContextConfiguration @ContextConfiguration}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 3.0
|
||||
* @see PropertiesBasedSpringJUnit4ClassRunnerAppCtxTests
|
||||
* @see ContextConfigurationWithPropertiesExtendingPropertiesTests
|
||||
*/
|
||||
@ContextConfiguration
|
||||
public class ContextConfigurationWithPropertiesExtendingPropertiesAndInheritedLoaderTests extends
|
||||
PropertiesBasedSpringJUnit4ClassRunnerAppCtxTests {
|
||||
|
||||
@Autowired
|
||||
private Pet dog;
|
||||
|
||||
@Autowired
|
||||
private String testString2;
|
||||
|
||||
|
||||
@Test
|
||||
public void verifyExtendedAnnotationAutowiredFields() {
|
||||
assertNotNull("The dog field should have been autowired.", this.dog);
|
||||
assertEquals("Fido", this.dog.getName());
|
||||
|
||||
assertNotNull("The testString2 field should have been autowired.", this.testString2);
|
||||
assertEquals("Test String #2", this.testString2);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
dog.(class)=org.springframework.beans.Pet
|
||||
dog.$0=Fido
|
||||
|
||||
testString2.(class)=java.lang.String
|
||||
testString2.$0=Test String #2
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.configuration;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.Pet;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.ContextLoader;
|
||||
import org.springframework.test.context.junit4.PropertiesBasedSpringJUnit4ClassRunnerAppCtxTests;
|
||||
import org.springframework.test.context.support.GenericPropertiesContextLoader;
|
||||
|
||||
/**
|
||||
* Integration tests which verify that the same custom {@link ContextLoader} can
|
||||
* be used at all levels within a test class hierarchy when the
|
||||
* <code>loader</code> is explicitly declared via {@link ContextConfiguration
|
||||
* @ContextConfiguration}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 3.0
|
||||
* @see PropertiesBasedSpringJUnit4ClassRunnerAppCtxTests
|
||||
* @see ContextConfigurationWithPropertiesExtendingPropertiesAndInheritedLoaderTests
|
||||
*/
|
||||
@ContextConfiguration(loader = GenericPropertiesContextLoader.class)
|
||||
public class ContextConfigurationWithPropertiesExtendingPropertiesTests extends
|
||||
PropertiesBasedSpringJUnit4ClassRunnerAppCtxTests {
|
||||
|
||||
@Autowired
|
||||
private Pet dog;
|
||||
|
||||
@Autowired
|
||||
private String testString2;
|
||||
|
||||
|
||||
@Test
|
||||
public void verifyExtendedAnnotationAutowiredFields() {
|
||||
assertNotNull("The dog field should have been autowired.", this.dog);
|
||||
assertEquals("Fido", this.dog.getName());
|
||||
|
||||
assertNotNull("The testString2 field should have been autowired.", this.testString2);
|
||||
assertEquals("Test String #2", this.testString2);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue