[SPR-8401] Documented TestContext support for @ActiveProfiles in the reference manual.
This commit is contained in:
parent
e1721976bb
commit
027c25d823
|
|
@ -1059,7 +1059,7 @@ public void testProcessRepeatedly() {
|
|||
</section>
|
||||
|
||||
<section id="testcontext-ctx-management">
|
||||
<title>Context management and caching</title>
|
||||
<title>Context management</title>
|
||||
|
||||
<para>Each <classname>TestContext</classname> provides context
|
||||
management and caching support for the test instance it is responsible
|
||||
|
|
@ -1267,14 +1267,15 @@ public class OrderServiceTest {
|
|||
linkend="integration-testing-annotations-spring" /> the TestContext
|
||||
framework does not allow you to declare <emphasis>both</emphasis>
|
||||
via <interfacename>@ContextConfiguration</interfacename>, but this
|
||||
does not mean that you cannot use both. If you want to use XML
|
||||
<emphasis role="bold">and</emphasis>
|
||||
does not mean that you cannot use both.</para>
|
||||
|
||||
<para>If you want to use XML <emphasis role="bold">and</emphasis>
|
||||
<interfacename>@Configuration</interfacename> classes to configure
|
||||
your tests, you will have to pick one as the <emphasis>entry
|
||||
point</emphasis>, and that one will have to include or import the
|
||||
other. For example, in XML you can include
|
||||
<interfacename>@Configuration</interfacename> classes in component
|
||||
scanning or define them as normal Spring beans; whereas, in a
|
||||
<interfacename>@Configuration</interfacename> classes via component
|
||||
scanning or define them as normal Spring beans in XML; whereas, in a
|
||||
<interfacename>@Configuration</interfacename> class you can use
|
||||
<interfacename>@ImportResource</interfacename> to import XML
|
||||
configuration files. Note that this behavior is semantically
|
||||
|
|
@ -1283,8 +1284,8 @@ public class OrderServiceTest {
|
|||
resource locations or a set of
|
||||
<interfacename>@Configuration</interfacename> classes that your
|
||||
production <interfacename>ApplicationContext</interfacename> will
|
||||
load, but you still have the freedom to include or import the other
|
||||
type of configuration.</para>
|
||||
loaded from, but you still have the freedom to include or import the
|
||||
other type of configuration.</para>
|
||||
</section>
|
||||
|
||||
<section id="testcontext-ctx-management-inheritance">
|
||||
|
|
@ -1357,6 +1358,184 @@ public class ExtendedTest extends BaseTest {
|
|||
}</programlisting>
|
||||
</section>
|
||||
|
||||
<section id="testcontext-ctx-management-env-profiles">
|
||||
<title>Context configuration with environment profiles</title>
|
||||
|
||||
<para>Spring 3.1 introduces first-class support in the framework for
|
||||
the notion of environments and profiles (a.k.a., bean definition
|
||||
profiles), and integration tests can now be configured to activate
|
||||
particular bean definition profiles for various testing scenarios.
|
||||
This is achieved by annotating a test class with the new
|
||||
@ActiveProfiles annotation and supplying a list of profiles that
|
||||
should be activated when loading the ApplicationContext for the
|
||||
test.</para>
|
||||
|
||||
<note>
|
||||
<para>@ActiveProfiles may be used with any implementation of the
|
||||
new SmartContextLoader SPI, but @ActiveProfiles is not supported
|
||||
with implementations of the older ContextLoader SPI.</para>
|
||||
</note>
|
||||
|
||||
<para>Let's take a look at some examples with XML configuration and
|
||||
@Configuration classes.</para>
|
||||
|
||||
<programlisting language="xml"><!-- app-config.xml -->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
|
||||
xmlns:jee="http://www.springframework.org/schema/jee"
|
||||
xsi:schemaLocation="...">
|
||||
|
||||
<bean id="transferService"
|
||||
class="com.bank.service.internal.DefaultTransferService">
|
||||
<constructor-arg ref="accountRepository"/>
|
||||
<constructor-arg ref="feePolicy"/>
|
||||
</bean>
|
||||
|
||||
<bean id="accountRepository"
|
||||
class="com.bank.repository.internal.JdbcAccountRepository">
|
||||
<constructor-arg ref="dataSource"/>
|
||||
</bean>
|
||||
|
||||
<bean id="feePolicy"
|
||||
class="com.bank.service.internal.ZeroFeePolicy"/>
|
||||
|
||||
<beans profile="dev">
|
||||
<jdbc:embedded-database id="dataSource">
|
||||
<jdbc:script
|
||||
location="classpath:com/bank/config/sql/schema.sql"/>
|
||||
<jdbc:script
|
||||
location="classpath:com/bank/config/sql/test-data.sql"/>
|
||||
</jdbc:embedded-database>
|
||||
</beans>
|
||||
|
||||
<beans profile="production">
|
||||
<jee:jndi-lookup id="dataSource"
|
||||
jndi-name="java:comp/env/jdbc/datasource"/>
|
||||
</beans>
|
||||
|
||||
</beans></programlisting>
|
||||
|
||||
<programlisting language="java">package com.bank.service;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
// ApplicationContext will be loaded from "classpath:/app-config.xml"
|
||||
@ContextConfiguration("/app-config.xml")
|
||||
@ActiveProfiles("dev")
|
||||
public class TransferServiceTest {
|
||||
|
||||
@Autowired
|
||||
private TransferService transferService;
|
||||
|
||||
@Test
|
||||
public void testTransferService() {
|
||||
// test the transferService
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>When TransferServiceTest is run, its ApplicationContext will
|
||||
be loaded from the app-config.xml configuration file in the root of
|
||||
the classpath. If you inspect app-config.xml you'll notice that the
|
||||
accountRepository bean has a dependency on a dataSource bean;
|
||||
however, dataSource is not defined as a top-level bean. Instead,
|
||||
dataSource is defined twice: once in the production profile and once
|
||||
in the dev profile.</para>
|
||||
|
||||
<para>By annotating TransferServiceTest with @ActiveProfiles("dev")
|
||||
we instruct the Spring TestContext Framework to load the
|
||||
ApplicationContext with the active profiles set to {"dev"}. As a
|
||||
result, an embedded database will be created, and the
|
||||
accountRepository bean will be wired with a reference to the
|
||||
development DataSource. And that's likely what we want in an
|
||||
integration test.</para>
|
||||
|
||||
<para>The following code listings demonstrate how to implement the
|
||||
same configuration and integration test but using @Configuration
|
||||
classes instead of XML.</para>
|
||||
|
||||
<programlisting language="java">@Configuration
|
||||
@Profile("dev")
|
||||
public class StandaloneDataConfig {
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
return new EmbeddedDatabaseBuilder()
|
||||
.setType(EmbeddedDatabaseType.HSQL)
|
||||
.addScript("classpath:com/bank/config/sql/schema.sql")
|
||||
.addScript("classpath:com/bank/config/sql/test-data.sql")
|
||||
.build();
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<programlisting language="java">@Configuration
|
||||
@Profile("production")
|
||||
public class JndiDataConfig {
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() throws Exception {
|
||||
Context ctx = new InitialContext();
|
||||
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<programlisting language="java">@Configuration
|
||||
@Profile("production")
|
||||
public class JndiDataConfig {
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() throws Exception {
|
||||
Context ctx = new InitialContext();
|
||||
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<programlisting language="java">package com.bank.service;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(
|
||||
classes={
|
||||
TransferServiceConfig.class,
|
||||
StandaloneDataConfig.class,
|
||||
JndiDataConfig.class})
|
||||
@ActiveProfiles("dev")
|
||||
public class TransferServiceTest {
|
||||
|
||||
@Autowired
|
||||
private TransferService transferService;
|
||||
|
||||
@Test
|
||||
public void testTransferService() {
|
||||
// test the transferService
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>In this variation, we have split the XML configuration into
|
||||
three independent @Configuration classes:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>TransferServiceConfig: acquires a dataSource via
|
||||
dependency injection using @Autowired</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>StandaloneDataConfig: defines a dataSource for an embedded
|
||||
database suitable for developer tests</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>JndiDataConfig: defines a dataSource that is retrieved
|
||||
from JNDI in a production environment</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>As with the XML-based configuration example, we still annotate
|
||||
TransferServiceTest with @ActiveProfiles("dev"), but this time we
|
||||
specify all three configuration classes via the
|
||||
@ContextConfiguration annotation. The body of the test class itself
|
||||
remains completely unchanged.</para>
|
||||
</section>
|
||||
|
||||
<section id="testcontext-ctx-management-caching">
|
||||
<title>Context caching</title>
|
||||
|
||||
|
|
@ -1364,11 +1543,12 @@ public class ExtendedTest extends BaseTest {
|
|||
<interfacename>ApplicationContext</interfacename> has been loaded
|
||||
for a test it will be reused for <emphasis
|
||||
role="bold">all</emphasis> subsequent tests that declare the same
|
||||
unique context configuration within the same process — for example,
|
||||
all tests run in a suite within an IDE or all tests run for the same
|
||||
project with a build framework like Ant or Maven. Thus the setup
|
||||
cost for loading an application context is incurred only once (per
|
||||
test suite), and subsequent test execution is much faster.</para>
|
||||
<emphasis>unique</emphasis> context configuration within the same
|
||||
process — for example, all tests run in a suite within an IDE or all
|
||||
tests run for the same project with a build framework like Ant or
|
||||
Maven. Thus the setup cost for loading an application context is
|
||||
incurred only once (per test suite), and subsequent test execution
|
||||
is much faster.</para>
|
||||
|
||||
<para>In the unlikely case that a test corrupts the application
|
||||
context and requires reloading — for example, by modifying a bean
|
||||
|
|
|
|||
Loading…
Reference in New Issue