From ec3052cb5fe090628153ad70148678158132cf62 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 17 Jul 2011 17:16:12 +0000 Subject: [PATCH] [SPR-8387] Fleshed out the implementation of DelegatingSmartContextLoader and corresponding tests. git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4712 50f2f4bb-b051-0410-bef5-90022cba6387 --- .../ContextConfigurationAttributes.java | 24 +++-- .../context/MergedContextConfiguration.java | 22 ++--- .../test/context/SmartContextLoader.java | 8 +- .../support/DelegatingSmartContextLoader.java | 62 +++++++----- .../DelegatingSmartContextLoaderTests.java | 98 ++++++++++++++++++- ...ContextLoaderTests$XmlTestCase-context.xml | 8 ++ 6 files changed, 170 insertions(+), 52 deletions(-) create mode 100644 org.springframework.test/src/test/resources/org/springframework/test/context/support/DelegatingSmartContextLoaderTests$XmlTestCase-context.xml diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/ContextConfigurationAttributes.java b/org.springframework.test/src/main/java/org/springframework/test/context/ContextConfigurationAttributes.java index 516c489b408..3c81bd5e77a 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/ContextConfigurationAttributes.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/ContextConfigurationAttributes.java @@ -102,6 +102,10 @@ public class ContextConfigurationAttributes { */ public ContextConfigurationAttributes(Class declaringClass, String[] locations, Class[] classes, boolean inheritLocations, Class contextLoaderClass) { + + Assert.notNull(declaringClass, "declaringClass must not be null"); + Assert.notNull(contextLoaderClass, "contextLoaderClass must not be null"); + this.declaringClass = declaringClass; this.locations = locations; this.classes = classes; @@ -115,7 +119,7 @@ public class ContextConfigurationAttributes { * @return the declaring class; never null */ public Class getDeclaringClass() { - return this.declaringClass; + return declaringClass; } /** @@ -130,7 +134,7 @@ public class ContextConfigurationAttributes { * @see #setLocations() */ public String[] getLocations() { - return this.locations; + return locations; } /** @@ -153,7 +157,7 @@ public class ContextConfigurationAttributes { * @see #setClasses() */ public Class[] getClasses() { - return this.classes; + return classes; } /** @@ -184,7 +188,7 @@ public class ContextConfigurationAttributes { * @see ContextConfiguration#inheritLocations */ public boolean isInheritLocations() { - return this.inheritLocations; + return inheritLocations; } /** @@ -194,7 +198,7 @@ public class ContextConfigurationAttributes { * @see ContextConfiguration#loader */ public Class getContextLoaderClass() { - return this.contextLoaderClass; + return contextLoaderClass; } /** @@ -204,11 +208,11 @@ public class ContextConfigurationAttributes { @Override public String toString() { return new ToStringCreator(this)// - .append("declaringClass", this.declaringClass)// - .append("locations", ObjectUtils.nullSafeToString(this.locations))// - .append("classes", ObjectUtils.nullSafeToString(this.classes))// - .append("inheritLocations", this.inheritLocations)// - .append("contextLoaderClass", this.contextLoaderClass)// + .append("declaringClass", declaringClass.getName())// + .append("locations", ObjectUtils.nullSafeToString(locations))// + .append("classes", ObjectUtils.nullSafeToString(classes))// + .append("inheritLocations", inheritLocations)// + .append("contextLoaderClass", contextLoaderClass.getName())// .toString(); } diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java b/org.springframework.test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java index fe73d727443..c64efab2f23 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java @@ -136,7 +136,7 @@ public class MergedContextConfiguration { * MergedContextConfiguration. */ public Class getTestClass() { - return this.testClass; + return testClass; } /** @@ -144,7 +144,7 @@ public class MergedContextConfiguration { * {@link #getTestClass() test class}. */ public String[] getLocations() { - return this.locations; + return locations; } /** @@ -152,7 +152,7 @@ public class MergedContextConfiguration { * {@link #getTestClass() test class}. */ public Class[] getClasses() { - return this.classes; + return classes; } /** @@ -160,7 +160,7 @@ public class MergedContextConfiguration { * {@link #getTestClass() test class}. */ public String[] getActiveProfiles() { - return this.activeProfiles; + return activeProfiles; } /** @@ -168,7 +168,7 @@ public class MergedContextConfiguration { * {@link #getTestClass() test class}. */ public ContextLoader getContextLoader() { - return this.contextLoader; + return contextLoader; } /** @@ -180,7 +180,7 @@ public class MergedContextConfiguration { * that was loaded using properties of this MergedContextConfiguration. */ public String getContextKey() { - return this.contextKey; + return contextKey; } /** @@ -190,12 +190,12 @@ public class MergedContextConfiguration { @Override public String toString() { return new ToStringCreator(this)// - .append("testClass", this.testClass)// - .append("locations", ObjectUtils.nullSafeToString(this.locations))// - .append("classes", ObjectUtils.nullSafeToString(this.classes))// - .append("activeProfiles", ObjectUtils.nullSafeToString(this.activeProfiles))// + .append("testClass", testClass)// + .append("locations", ObjectUtils.nullSafeToString(locations))// + .append("classes", ObjectUtils.nullSafeToString(classes))// + .append("activeProfiles", ObjectUtils.nullSafeToString(activeProfiles))// .append("contextLoader", nullSafeToString(contextLoader))// - .append("contextKey", this.contextKey)// + .append("contextKey", contextKey)// .toString(); } diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/SmartContextLoader.java b/org.springframework.test/src/main/java/org/springframework/test/context/SmartContextLoader.java index 16f8655e0a8..15b08e16500 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/SmartContextLoader.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/SmartContextLoader.java @@ -37,7 +37,8 @@ import org.springframework.context.ApplicationContext; * {@link #processContextConfiguration(ContextConfigurationAttributes) processContextConfiguration()} * should be merged for all classes in the hierarchy of the root test class and * then supplied to {@link #loadContext(MergedContextConfiguration) loadContext()}. - * Even though SmartContextLoader extends ContextLoader, + * + *

Even though SmartContextLoader extends ContextLoader, * clients should favor SmartContextLoader-specific methods over those * defined in ContextLoader, particularly because a * SmartContextLoader may choose not to support methods defined in @@ -63,9 +64,8 @@ public interface SmartContextLoader extends ContextLoader { /** * Determines if this SmartContextLoader generates default resource - * locations or - * {@link org.springframework.context.annotation.Configuration configuration classes} - * if the locations or classes + * locations or {@link org.springframework.context.annotation.Configuration + * configuration classes} if the locations or classes * present in the {@link ContextConfigurationAttributes} provided to * {@link #processContextConfiguration()} are null or empty. *

Returning a value of true signals not only that this diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/support/DelegatingSmartContextLoader.java b/org.springframework.test/src/main/java/org/springframework/test/context/support/DelegatingSmartContextLoader.java index 2be4a49a063..77cce001cd0 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/support/DelegatingSmartContextLoader.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/support/DelegatingSmartContextLoader.java @@ -66,34 +66,50 @@ public class DelegatingSmartContextLoader implements SmartContextLoader { final boolean originallyHadResources = configAttributes.hasResources(); - for (SmartContextLoader loader : candidates) { - if (logger.isDebugEnabled()) { - logger.debug(String.format("Potentially delegating to %s to process context configuration [%s].", - loader.getClass().getName(), configAttributes)); - } - - // If the original locations and classes were not empty, there's no - // need to bother with default generation checks; just let each - // loader process the configuration. - if (originallyHadResources) { + // If the original locations and classes were not empty, there's no + // need to bother with default generation checks; just let each + // loader process the configuration. + if (originallyHadResources) { + for (SmartContextLoader loader : candidates) { + if (logger.isDebugEnabled()) { + logger.debug(String.format("Delegating to %s to process context configuration [%s].", + loader.getClass().getName(), configAttributes)); + } loader.processContextConfiguration(configAttributes); } - // Otherwise, if the loader claims to generate defaults, let it - // process the configuration. - else if (loader.generatesDefaults()) { - loader.processContextConfiguration(configAttributes); - if (configAttributes.hasResources() && logger.isInfoEnabled()) { - logger.info(String.format("SmartContextLoader candidate %s " - + "generated defaults for context configuration [%s].", loader, configAttributes)); + } + else if (generatesDefaults()) { + for (SmartContextLoader loader : candidates) { + boolean defaultResourcesAlreadyGenerated = configAttributes.hasResources(); + // If defaults haven't already been generated and the loader + // claims to generate defaults, let it process the + // configuration. + if (!defaultResourcesAlreadyGenerated && loader.generatesDefaults()) { + if (logger.isDebugEnabled()) { + logger.debug(String.format( + "Delegating to %s to generate defaults for context configuration [%s].", + loader.getClass().getName(), configAttributes)); + } + + loader.processContextConfiguration(configAttributes); + + if (configAttributes.hasResources()) { + if (logger.isInfoEnabled()) { + logger.info(String.format("SmartContextLoader candidate %s " + + "generated defaults for context configuration [%s].", loader, configAttributes)); + } + } } } - } - // If any loader claims to generate defaults but none actually did, - // throw an exception. - if (generatesDefaults() && !originallyHadResources && !configAttributes.hasResources()) { - throw new IllegalStateException(String.format("None of the SmartContextLoader candidates %s " - + "was able to generate defaults for context configuration [%s].", candidates, configAttributes)); + // If any loader claims to generate defaults but none actually did, + // throw an exception. + if (!configAttributes.hasResources()) { + throw new IllegalStateException( + String.format("None of the SmartContextLoader candidates %s " + + "was able to generate defaults for context configuration [%s].", candidates, + configAttributes)); + } } } diff --git a/org.springframework.test/src/test/java/org/springframework/test/context/support/DelegatingSmartContextLoaderTests.java b/org.springframework.test/src/test/java/org/springframework/test/context/support/DelegatingSmartContextLoaderTests.java index c482149cae2..222b1620612 100644 --- a/org.springframework.test/src/test/java/org/springframework/test/context/support/DelegatingSmartContextLoaderTests.java +++ b/org.springframework.test/src/test/java/org/springframework/test/context/support/DelegatingSmartContextLoaderTests.java @@ -16,11 +16,21 @@ package org.springframework.test.context.support; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfigurationAttributes; +import org.springframework.test.context.ContextLoader; import org.springframework.test.context.MergedContextConfiguration; +import org.springframework.util.ObjectUtils; /** * Unit tests for {@link DelegatingSmartContextLoader}. @@ -36,6 +46,10 @@ public class DelegatingSmartContextLoaderTests { private final DelegatingSmartContextLoader loader = new DelegatingSmartContextLoader(); + private static void assertEmpty(Object[] array) { + assertTrue(ObjectUtils.isEmpty(array)); + } + // --- SmartContextLoader -------------------------------------------------- @Test @@ -43,9 +57,49 @@ public class DelegatingSmartContextLoaderTests { assertTrue(loader.generatesDefaults()); } + @Test(expected = IllegalStateException.class) + public void processContextConfigurationWithoutLocationsAndConfigurationClassesForBogusTestClass() { + ContextConfigurationAttributes configAttributes = new ContextConfigurationAttributes(getClass(), + EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, true, ContextLoader.class); + loader.processContextConfiguration(configAttributes); + } + + @Test + public void processContextConfigurationWithDefaultXmlConfigGeneration() { + ContextConfigurationAttributes configAttributes = new ContextConfigurationAttributes(XmlTestCase.class, + EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, true, ContextLoader.class); + loader.processContextConfiguration(configAttributes); + assertEquals(1, configAttributes.getLocations().length); + assertEmpty(configAttributes.getClasses()); + } + + @Test + public void processContextConfigurationWithDefaultConfigurationClassGeneration() { + ContextConfigurationAttributes configAttributes = new ContextConfigurationAttributes(ConfigClassTestCase.class, + EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, true, ContextLoader.class); + loader.processContextConfiguration(configAttributes); + assertEquals(1, configAttributes.getClasses().length); + assertEmpty(configAttributes.getLocations()); + } + + @Test + public void processContextConfigurationWithLocation() { + String[] locations = new String[] { "classpath:/foo.xml" }; + ContextConfigurationAttributes configAttributes = new ContextConfigurationAttributes(getClass(), locations, + EMPTY_CLASS_ARRAY, true, ContextLoader.class); + loader.processContextConfiguration(configAttributes); + assertArrayEquals(locations, configAttributes.getLocations()); + assertEmpty(configAttributes.getClasses()); + } + @Test - public void processContextConfiguration() { - // TODO test processContextConfiguration(). + public void processContextConfigurationWithConfigurationClass() { + Class[] classes = new Class[] { getClass() }; + ContextConfigurationAttributes configAttributes = new ContextConfigurationAttributes(getClass(), + EMPTY_STRING_ARRAY, classes, true, ContextLoader.class); + loader.processContextConfiguration(configAttributes); + assertArrayEquals(classes, configAttributes.getClasses()); + assertEmpty(configAttributes.getLocations()); } @Test(expected = IllegalArgumentException.class) @@ -95,9 +149,29 @@ public class DelegatingSmartContextLoaderTests { loader.loadContext(mergedConfig); } + private void assertApplicationContextLoadsAndContainsFooString(MergedContextConfiguration mergedConfig) + throws Exception { + ApplicationContext applicationContext = loader.loadContext(mergedConfig); + assertNotNull(applicationContext); + assertEquals("foo", applicationContext.getBean(String.class)); + assertTrue(applicationContext instanceof ConfigurableApplicationContext); + ((ConfigurableApplicationContext) applicationContext).close(); + } + @Test - public void loadContext() { - // TODO test loadContext(). + public void loadContextWithXmlConfig() throws Exception { + MergedContextConfiguration mergedConfig = new MergedContextConfiguration( + XmlTestCase.class, + new String[] { "classpath:/org/springframework/test/context/support/DelegatingSmartContextLoaderTests$XmlTestCase-context.xml" }, + EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); + assertApplicationContextLoadsAndContainsFooString(mergedConfig); + } + + @Test + public void loadContextWithConfigurationClass() throws Exception { + MergedContextConfiguration mergedConfig = new MergedContextConfiguration(ConfigClassTestCase.class, + EMPTY_STRING_ARRAY, new Class[] { ConfigClassTestCase.Config.class }, EMPTY_STRING_ARRAY, loader); + assertApplicationContextLoadsAndContainsFooString(mergedConfig); } // --- ContextLoader ------------------------------------------------------- @@ -112,4 +186,20 @@ public class DelegatingSmartContextLoaderTests { loader.loadContext(EMPTY_STRING_ARRAY); } + + static class XmlTestCase { + } + + static class ConfigClassTestCase { + + @Configuration + static class Config { + + @Bean + public String foo() { + return new String("foo"); + } + } + } + } diff --git a/org.springframework.test/src/test/resources/org/springframework/test/context/support/DelegatingSmartContextLoaderTests$XmlTestCase-context.xml b/org.springframework.test/src/test/resources/org/springframework/test/context/support/DelegatingSmartContextLoaderTests$XmlTestCase-context.xml new file mode 100644 index 00000000000..965ab428bf7 --- /dev/null +++ b/org.springframework.test/src/test/resources/org/springframework/test/context/support/DelegatingSmartContextLoaderTests$XmlTestCase-context.xml @@ -0,0 +1,8 @@ + + + + + +