From 1bb5b2188166d6bba954135a385a4fcc2b582cd5 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 29 Sep 2011 20:54:26 +0000 Subject: [PATCH] [SPR-8240] Introduced new "Context management with @Configuration classes" section; fleshing out sections on context configuration inheritance and context caching. --- spring-framework-reference/src/testing.xml | 250 +++++++++++++++------ 1 file changed, 183 insertions(+), 67 deletions(-) diff --git a/spring-framework-reference/src/testing.xml b/spring-framework-reference/src/testing.xml index 3ceb985e24..7df8c3902d 100644 --- a/spring-framework-reference/src/testing.xml +++ b/spring-framework-reference/src/testing.xml @@ -1068,13 +1068,15 @@ public void testProcessRepeatedly() { test class implements the ApplicationContextAware interface, a reference to the ApplicationContext is supplied - to the test instance, if the - DependencyInjectionTestExecutionListener is - configured, which is the default. + to the test instance. Note that dependency injection support is + provided by the + DependencyInjectionTestExecutionListener which + is configured by default. In addition, AbstractJUnit4SpringContextTests and - AbstractTestNGSpringContextTests already - implement ApplicationContextAware and - therefore provide this functionality out-of-the-box. + AbstractTestNGSpringContextTests implement + ApplicationContextAware and therefore + provide access to the ApplicationContext + out-of-the-box. @Autowired ApplicationContext @@ -1109,41 +1111,33 @@ public class MyTest { context from a default location or default configuration classes. -
- XML-based configuration - - For example, GenericXmlContextLoader - generates a default location based on the name of the test class. If - your class is named com.example.MyTest, - GenericXmlContextLoader loads your - application context from - "classpath:/com/example/MyTest-context.xml". - - package com.example; - -@RunWith(SpringJUnit4ClassRunner.class) -// ApplicationContext will be loaded from "classpath:/com/example/MyTest-context.xml" -@ContextConfiguration -public class MyTest { - // class body... -} + The following sections explain how to configure and manage + ApplicationContexts via XML + configuration files and @Configuration + classes using Spring's + @ContextConfiguration + annotation. - If the default location does not suit your needs, you can - explicitly configure the locations attribute of - @ContextConfiguration with an array - that contains the resource locations of XML configuration metadata - (assuming an XML-capable - ContextLoader has been configured, - which is the default). A plain path, for example - "context.xml", will be treated as a classpath - resource from the same package in which the test class is defined. A - path starting with a slash is treated as a fully qualified classpath - location, for example "/org/example/config.xml". - A path which represents a URL (i.e., a path prefixed with +
+ Context management with XML resources + + To load an + ApplicationContextAware for your + tests from XML configuration files, annotate your test class with + @ContextConfiguration and configure + the locations attribute with an array that + contains the resource locations of XML configuration metadata. A + plain path — for example "context.xml" — will be + treated as a classpath resource from the package in which the test + class is defined. A path starting with a slash is treated as a fully + qualified classpath location, for example + "/org/example/config.xml". A path which + represents a URL (i.e., a path prefixed with classpath:, file:, http:, etc.) will be used as is. Alternatively, you can implement and configure your - own custom ContextLoader. + own custom ContextLoader for advanced + use cases. @RunWith(SpringJUnit4ClassRunner.class) // ApplicationContext will be loaded from "/applicationContext.xml" and @@ -1166,29 +1160,120 @@ public class MyTest { @ContextConfiguration({"/applicationContext.xml", "/applicationContext-test.xml"}) public class MyTest { // class body... +} + + If you omit both the locations and + value attributes from the + @ContextConfiguration annotation, the + TestContext framework will attempt to detect a default XML resource + location. Specifically, + GenericXmlContextLoader detects a default + location based on the name of the test class. If your class is named + com.example.MyTest, + GenericXmlContextLoader loads your + application context from + "classpath:/com/example/MyTest-context.xml". + + package com.example; + +@RunWith(SpringJUnit4ClassRunner.class) +// ApplicationContext will be loaded from "classpath:/com/example/MyTest-context.xml" +@ContextConfiguration +public class MyTest { + // class body... +} +
+ +
+ Context management with @Configuration classes + + To load an + ApplicationContextAware for your + tests from @Configuration classes, + annotate your test class with + @ContextConfiguration and configure + the classes attribute with an array that contains + class references to configuration classes. Alternatively, you can + implement and configure your own custom + ContextLoader for advanced use + cases. + + @RunWith(SpringJUnit4ClassRunner.class) +// ApplicationContext will be loaded from AppConfig and TestAppConfig +@ContextConfiguration(classes={AppConfig.class, TestAppConfig.class}) +public class MyTest { + // class body... +} + + If you omit the classes attribute from the + @ContextConfiguration annotation, the + TestContext framework will attempt to detect the presence of default + configuration classes. Specifically, + AnnotationConfigContextLoader will detect all + static inner classes of the annotated test class that meet the + requirements for configuration class implementations as specified in + the Javadoc for @Configuration (see + for further details). In the following + example, the OrderServiceTest class declares + a static inner configuration class named + Config that will be automatically used to + load the ApplicationContext for the + test class. Note that the name of the configuration class is + arbitrary. In addition, a test class can contain more than one + static inner configuration class if desired. + + package com.example; + +@RunWith(SpringJUnit4ClassRunner.class) +// ApplicationContext will be loaded from the static inner Config class +@ContextConfiguration +public class OrderServiceTest { + + @Configuration + static class Config { + + // this bean will be injected into the OrderServiceTest class + @Bean + public OrderService orderService() { + OrderService orderService = new OrderServiceImpl(); + // set properties, etc. + return orderService; + } + } + + @Autowired + private OrderService orderService; + + @Test + public void testOrderService() { + // test the orderService + } + }
- Configuration inheritance - - @ContextConfiguration also - supports a boolean inheritLocations attribute - that denotes whether resource locations from superclasses should be - inherited. The default value is - true, which means that an annotated class - inherits the resource locations defined by an annotated superclass. - Specifically, the resource locations for an annotated class are - appended to the list of resource locations defined by an annotated - superclass. Thus, subclasses have the option of - extending the list of resource locations. In - the following example, the + Context configuration inheritance + + @ContextConfiguration supports + a boolean inheritLocations attribute that denotes + whether resource locations or configuration classes declared by + superclasses should be inherited. The default + value is true, which means that an annotated + class inherits the resource locations or configuration classes + declared by an annotated superclass. Specifically, the resource + locations or configuration classes for an annotated test class are + appended to the list of resource locations or configuration classes + declared by an annotated superclass. Thus, subclasses have the + option of extending the list of resource + locations or configuration classes. In the following example that + uses XML resource locations, the ApplicationContext for - ExtendedTest is loaded from - "/base-context.xml" and - "/extended-context.xml", in that order. Beans defined in - "/extended-context.xml" may therefore override those defined in - "/base-context.xml". + ExtendedTest will be loaded from + "base-context.xml" and + "extended-context.xml", in that order. Beans defined in + "extended-context.xml" may therefore override + (i.e., replace) those defined in "base-context.xml". @RunWith(SpringJUnit4ClassRunner.class) // ApplicationContext will be loaded from "/base-context.xml" in the root of the classpath @@ -1204,23 +1289,54 @@ public class ExtendedTest extends BaseTest { // class body... } - If inheritLocations is set to - false, the resource locations for the annotated - class shadow and effectively replace any resource locations defined - by a superclass. + Similarly, in the following example that uses configuration + classes, the ApplicationContext for + ExtendedTest will be loaded from the + BaseConfig and ExtendedConfig + configuration classes, in that order. Beans defined in + ExtendedConfig may therefore override (i.e., + replace) those defined in BaseConfig. + + @RunWith(SpringJUnit4ClassRunner.class) +// ApplicationContext will be loaded from "/base-context.xml" in the root of the classpath +@ContextConfiguration(classes=BaseConfig.class) +public class BaseTest { + // class body... +} + +// ApplicationContext will be loaded from "/base-context.xml" and "/extended-context.xml" +// in the root of the classpath +@ContextConfiguration(classes=ExtendedConfig.class) +public class ExtendedTest extends BaseTest { + // class body... +} + + If @ContextConfiguration's + inheritLocations attribute is set to + false, the resource locations or configuration + classes for the annotated class shadow and effectively replace any + resource locations defined by a superclass.
Context caching - By default, once loaded, the configured - ApplicationContext is reused for each - test. Thus the setup cost is incurred only once (per test suite), - and subsequent test execution is much faster. In the unlikely case - that a test corrupts the application context and requires reloading - — for example, by modifying a bean definition or the state of an - application object — you can annotate your test class or test method - with @DirtiesContext (assuming + By default, once an + ApplicationContext has been loaded + for a test it will be reused for all subsequent tests that declare the same + unique context configuration within the same process — for example, + all tests run in a suite in an IDE or all tests run for the same + project from a build framework like Ant or Maven. Thus the setup + cost for loading the application context is incurred only once (per + test suite), and subsequent test execution is much faster. + + In the unlikely case that a test corrupts the application + context and requires reloading — for example, by modifying a bean + definition or the state of an application object — you can annotate + your test class or test method with + @DirtiesContext (assuming DirtiesContextTestExecutionListener has been configured, which is the default). This instructs Spring to reload the configuration and rebuild the application context before