@@ -1059,7 +1059,7 @@ public void testProcessRepeatedly() {
1059
1059
</section >
1060
1060
1061
1061
<section id =" testcontext-ctx-management" >
1062
- <title >Context management and caching </title >
1062
+ <title >Context management</title >
1063
1063
1064
1064
<para >Each <classname >TestContext</classname > provides context
1065
1065
management and caching support for the test instance it is responsible
@@ -1267,14 +1267,15 @@ public class OrderServiceTest {
1267
1267
linkend =" integration-testing-annotations-spring" /> the TestContext
1268
1268
framework does not allow you to declare <emphasis >both</emphasis >
1269
1269
via <interfacename >@ContextConfiguration</interfacename >, but this
1270
- does not mean that you cannot use both. If you want to use XML
1271
- <emphasis role =" bold" >and</emphasis >
1270
+ does not mean that you cannot use both.</para >
1271
+
1272
+ <para >If you want to use XML <emphasis role =" bold" >and</emphasis >
1272
1273
<interfacename >@Configuration</interfacename > classes to configure
1273
1274
your tests, you will have to pick one as the <emphasis >entry
1274
1275
point</emphasis >, and that one will have to include or import the
1275
1276
other. For example, in XML you can include
1276
- <interfacename >@Configuration</interfacename > classes in component
1277
- scanning or define them as normal Spring beans; whereas, in a
1277
+ <interfacename >@Configuration</interfacename > classes via component
1278
+ scanning or define them as normal Spring beans in XML ; whereas, in a
1278
1279
<interfacename >@Configuration</interfacename > class you can use
1279
1280
<interfacename >@ImportResource</interfacename > to import XML
1280
1281
configuration files. Note that this behavior is semantically
@@ -1283,8 +1284,8 @@ public class OrderServiceTest {
1283
1284
resource locations or a set of
1284
1285
<interfacename >@Configuration</interfacename > classes that your
1285
1286
production <interfacename >ApplicationContext</interfacename > will
1286
- load , but you still have the freedom to include or import the other
1287
- type of configuration.</para >
1287
+ loaded from , but you still have the freedom to include or import the
1288
+ other type of configuration.</para >
1288
1289
</section >
1289
1290
1290
1291
<section id =" testcontext-ctx-management-inheritance" >
@@ -1357,18 +1358,197 @@ public class ExtendedTest extends BaseTest {
1357
1358
}</programlisting >
1358
1359
</section >
1359
1360
1361
+ <section id =" testcontext-ctx-management-env-profiles" >
1362
+ <title >Context configuration with environment profiles</title >
1363
+
1364
+ <para >Spring 3.1 introduces first-class support in the framework for
1365
+ the notion of environments and profiles (a.k.a., bean definition
1366
+ profiles), and integration tests can now be configured to activate
1367
+ particular bean definition profiles for various testing scenarios.
1368
+ This is achieved by annotating a test class with the new
1369
+ @ActiveProfiles annotation and supplying a list of profiles that
1370
+ should be activated when loading the ApplicationContext for the
1371
+ test.</para >
1372
+
1373
+ <note >
1374
+ <para >@ActiveProfiles may be used with any implementation of the
1375
+ new SmartContextLoader SPI, but @ActiveProfiles is not supported
1376
+ with implementations of the older ContextLoader SPI.</para >
1377
+ </note >
1378
+
1379
+ <para >Let's take a look at some examples with XML configuration and
1380
+ @Configuration classes.</para >
1381
+
1382
+ <programlisting language =" xml" >< !-- app-config.xml -->
1383
+ < beans xmlns="http://www.springframework.org/schema/beans"
1384
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1385
+ xmlns:jdbc="http://www.springframework.org/schema/jdbc"
1386
+ xmlns:jee="http://www.springframework.org/schema/jee"
1387
+ xsi:schemaLocation="...">
1388
+
1389
+ < bean id="transferService"
1390
+ class="com.bank.service.internal.DefaultTransferService">
1391
+ < constructor-arg ref="accountRepository"/>
1392
+ < constructor-arg ref="feePolicy"/>
1393
+ < /bean>
1394
+
1395
+ < bean id="accountRepository"
1396
+ class="com.bank.repository.internal.JdbcAccountRepository">
1397
+ < constructor-arg ref="dataSource"/>
1398
+ < /bean>
1399
+
1400
+ < bean id="feePolicy"
1401
+ class="com.bank.service.internal.ZeroFeePolicy"/>
1402
+
1403
+ < beans profile="dev">
1404
+ < jdbc:embedded-database id="dataSource">
1405
+ < jdbc:script
1406
+ location="classpath:com/bank/config/sql/schema.sql"/>
1407
+ < jdbc:script
1408
+ location="classpath:com/bank/config/sql/test-data.sql"/>
1409
+ < /jdbc:embedded-database>
1410
+ < /beans>
1411
+
1412
+ < beans profile="production">
1413
+ < jee:jndi-lookup id="dataSource"
1414
+ jndi-name="java:comp/env/jdbc/datasource"/>
1415
+ < /beans>
1416
+
1417
+ < /beans> </programlisting >
1418
+
1419
+ <programlisting language =" java" >package com.bank.service;
1420
+
1421
+ @RunWith(SpringJUnit4ClassRunner.class)
1422
+ // ApplicationContext will be loaded from "classpath:/app-config.xml"
1423
+ @ContextConfiguration("/app-config.xml")
1424
+ @ActiveProfiles("dev")
1425
+ public class TransferServiceTest {
1426
+
1427
+ @Autowired
1428
+ private TransferService transferService;
1429
+
1430
+ @Test
1431
+ public void testTransferService() {
1432
+ // test the transferService
1433
+ }
1434
+ }</programlisting >
1435
+
1436
+ <para >When TransferServiceTest is run, its ApplicationContext will
1437
+ be loaded from the app-config.xml configuration file in the root of
1438
+ the classpath. If you inspect app-config.xml you'll notice that the
1439
+ accountRepository bean has a dependency on a dataSource bean;
1440
+ however, dataSource is not defined as a top-level bean. Instead,
1441
+ dataSource is defined twice: once in the production profile and once
1442
+ in the dev profile.</para >
1443
+
1444
+ <para >By annotating TransferServiceTest with @ActiveProfiles("dev")
1445
+ we instruct the Spring TestContext Framework to load the
1446
+ ApplicationContext with the active profiles set to {"dev"}. As a
1447
+ result, an embedded database will be created, and the
1448
+ accountRepository bean will be wired with a reference to the
1449
+ development DataSource. And that's likely what we want in an
1450
+ integration test.</para >
1451
+
1452
+ <para >The following code listings demonstrate how to implement the
1453
+ same configuration and integration test but using @Configuration
1454
+ classes instead of XML.</para >
1455
+
1456
+ <programlisting language =" java" >@Configuration
1457
+ @Profile("dev")
1458
+ public class StandaloneDataConfig {
1459
+
1460
+ @Bean
1461
+ public DataSource dataSource() {
1462
+ return new EmbeddedDatabaseBuilder()
1463
+ .setType(EmbeddedDatabaseType.HSQL)
1464
+ .addScript("classpath:com/bank/config/sql/schema.sql")
1465
+ .addScript("classpath:com/bank/config/sql/test-data.sql")
1466
+ .build();
1467
+ }
1468
+ }</programlisting >
1469
+
1470
+ <programlisting language =" java" >@Configuration
1471
+ @Profile("production")
1472
+ public class JndiDataConfig {
1473
+
1474
+ @Bean
1475
+ public DataSource dataSource() throws Exception {
1476
+ Context ctx = new InitialContext();
1477
+ return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
1478
+ }
1479
+ }</programlisting >
1480
+
1481
+ <programlisting language =" java" >@Configuration
1482
+ @Profile("production")
1483
+ public class JndiDataConfig {
1484
+
1485
+ @Bean
1486
+ public DataSource dataSource() throws Exception {
1487
+ Context ctx = new InitialContext();
1488
+ return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
1489
+ }
1490
+ }</programlisting >
1491
+
1492
+ <programlisting language =" java" >package com.bank.service;
1493
+
1494
+ @RunWith(SpringJUnit4ClassRunner.class)
1495
+ @ContextConfiguration(
1496
+ classes={
1497
+ TransferServiceConfig.class,
1498
+ StandaloneDataConfig.class,
1499
+ JndiDataConfig.class})
1500
+ @ActiveProfiles("dev")
1501
+ public class TransferServiceTest {
1502
+
1503
+ @Autowired
1504
+ private TransferService transferService;
1505
+
1506
+ @Test
1507
+ public void testTransferService() {
1508
+ // test the transferService
1509
+ }
1510
+ }</programlisting >
1511
+
1512
+ <para >In this variation, we have split the XML configuration into
1513
+ three independent @Configuration classes:</para >
1514
+
1515
+ <itemizedlist >
1516
+ <listitem >
1517
+ <para >TransferServiceConfig: acquires a dataSource via
1518
+ dependency injection using @Autowired</para >
1519
+ </listitem >
1520
+
1521
+ <listitem >
1522
+ <para >StandaloneDataConfig: defines a dataSource for an embedded
1523
+ database suitable for developer tests</para >
1524
+ </listitem >
1525
+
1526
+ <listitem >
1527
+ <para >JndiDataConfig: defines a dataSource that is retrieved
1528
+ from JNDI in a production environment</para >
1529
+ </listitem >
1530
+ </itemizedlist >
1531
+
1532
+ <para >As with the XML-based configuration example, we still annotate
1533
+ TransferServiceTest with @ActiveProfiles("dev"), but this time we
1534
+ specify all three configuration classes via the
1535
+ @ContextConfiguration annotation. The body of the test class itself
1536
+ remains completely unchanged.</para >
1537
+ </section >
1538
+
1360
1539
<section id =" testcontext-ctx-management-caching" >
1361
1540
<title >Context caching</title >
1362
1541
1363
1542
<para >By default, once an
1364
1543
<interfacename >ApplicationContext</interfacename > has been loaded
1365
1544
for a test it will be reused for <emphasis
1366
1545
role =" bold" >all</emphasis > subsequent tests that declare the same
1367
- unique context configuration within the same process — for example,
1368
- all tests run in a suite within an IDE or all tests run for the same
1369
- project with a build framework like Ant or Maven. Thus the setup
1370
- cost for loading an application context is incurred only once (per
1371
- test suite), and subsequent test execution is much faster.</para >
1546
+ <emphasis >unique</emphasis > context configuration within the same
1547
+ process — for example, all tests run in a suite within an IDE or all
1548
+ tests run for the same project with a build framework like Ant or
1549
+ Maven. Thus the setup cost for loading an application context is
1550
+ incurred only once (per test suite), and subsequent test execution
1551
+ is much faster.</para >
1372
1552
1373
1553
<para >In the unlikely case that a test corrupts the application
1374
1554
context and requires reloading — for example, by modifying a bean
0 commit comments