diff --git a/spring-framework-reference/src/testing.xml b/spring-framework-reference/src/testing.xml
index 26f74d3b6c5..0190fb22d6a 100644
--- a/spring-framework-reference/src/testing.xml
+++ b/spring-framework-reference/src/testing.xml
@@ -11,8 +11,8 @@
chapter focuses on the value-add of the IoC principle to unit testing and on the benefits of Spring
Framework integration testing.
- (A thorough treatment of testing in the enterprise is beyond the scope of
- this chapter.)
+ (A thorough treatment of testing in the enterprise is beyond the
+ scope of this chapter.)
@@ -159,11 +159,11 @@
The Spring Framework provides first-class support for
integration testing in
the spring-test module.
- The name of the actual jar file might include the release
+ The name of the actual JAR file might include the release
version and might also be in the
long org.springframework.test form,
depending on where you got it from (see
- the section on Dependency
+ the section on Dependency
Management for an explanation). This library includes
the org.springframework.test package, which
contains valuable classes for integration testing with a Spring
@@ -248,12 +248,12 @@
By default, once loaded, the configured
ApplicationContext is reused for each
- test. Thus the setup cost is incurred only once (per test fixture),
+ 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 — a Spring testing support mechanism causes the
- test fixture to reload the configurations and rebuilds the application
+ application object — the TestContext framework can be configured
+ to reload the configurations and rebuild the application
context before executing the next test.See context management and caching with the
As an example, consider the scenario where we have a class,
- HibernateTitleDao, that performs data access
+ HibernateTitleRepository, that performs data access
logic for say, the Title domain object. We want
to write integration tests that test all of the following
areas:
@@ -284,7 +284,7 @@
The Spring configuration: basically, is everything related
to the configuration of the
- HibernateTitleDao bean correct and
+ HibernateTitleRepository bean correct and
present?
@@ -295,7 +295,7 @@
- The logic of the HibernateTitleDao:
+ The logic of the HibernateTitleRepository:
does the configured instance of this class perform as
anticipated?
@@ -521,7 +521,7 @@ public void testProcessWhichDirtiesAppCtx() {
TestExecutionListeners should be
registered with the TestContextManager.
Typically, @TestExecutionListeners
- are used in conjunction with
+ is used in conjunction with
@ContextConfiguration.@ContextConfiguration
@@ -593,7 +593,7 @@ public void testProcessWithoutRollback() {
Indicates that the annotated public void
method should be executed before a transaction
is started for test methods configured to run within a transaction
- through the @Transactional
+ via the @Transactional
annotation.@BeforeTransaction
@@ -609,7 +609,7 @@ public void beforeTransaction() {
Indicates that the annotated public void
method should be executed after a transaction
has ended for test methods configured to run within a transaction
- through the @Transactional
+ via the @Transactional
annotation.@AfterTransaction
@@ -870,7 +870,7 @@ public void testProcessRepeatedly() {
In addition to generic testing infrastructure, the TestContext
framework provides explicit support for JUnit 3.8.2, JUnit 4.5+, and
TestNG 5.12 in the form of abstract support classes.
- For JUnit 4.5+, the framework also provides a custom
+ For JUnit 4.5+, the framework also provides a custom JUnit
Runner that allows one to write test
classes that are not required to extend a particular class
hierarchy.
@@ -1017,8 +1017,8 @@ public class MyTest {
class level. If your test class does not explicitly declare
application context resource locations, the
configured ContextLoader determines how
- and whether to load a context from a default set of locations. For
- example, GenericXmlContextLoader , which is the
+ and whether to load a context from a default location. For
+ example, GenericXmlContextLoader, which is the
default ContextLoader, generates a
default location based on the name of the test class. If your class is
named com.example.MyTest,
@@ -1036,22 +1036,25 @@ public class MyTest {
}If the default location does not suit your needs, you can
- configure explicitly the locations attribute of
+ 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) — typically in the classpath
- — used to configure the application. (See the following code example.)
- This location will be the same, or nearly the same, as the list of
- configuration locations specified in web.xml or
- other deployment configuration. Alternatively, you can implement and
- configure your own custom
+ 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
+ classpath:, file:,
+ http:, etc.) will be used as is.
+ Alternatively, you can implement and configure your own custom
ContextLoader.@RunWith(SpringJUnit4ClassRunner.class)
// ApplicationContext will be loaded from "/applicationContext.xml" and "/applicationContext-test.xml"// in the root of the classpath
-@ContextConfiguration({"/applicationContext.xml", "/applicationContext-test.xml"})
+@ContextConfiguration(locations={"/applicationContext.xml", "/applicationContext-test.xml"})
public class MyTest {
// class body...
}
@@ -1062,7 +1065,9 @@ public class MyTest {
to configure a custom ContextLoader,
you can omit the declaration of the locations
attribute name and declare the resource locations by using the
- shorthand format demonstrated in the following example.
+ shorthand format demonstrated in the following example.
+
+ @ContextConfiguration also supports a
boolean inheritLocations attribute that denotes
whether resource locations from superclasses should be
@@ -1073,8 +1078,7 @@ public class MyTest {
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
- ApplicationContext for
+ following example, 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
@@ -1096,22 +1100,21 @@ public class ExtendedTest extends BaseTest {
If inheritLocations is set to
false, the resource locations for the annotated
- class shadows and effectively replaces any resource locations defined
+ class shadow and effectively replace any resource locations defined
by a superclass.By default, once loaded, the configured
ApplicationContext is reused for each
- test. Thus the setup cost is incurred only once (per test fixture),
+ 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 dirties (modifies)
- the application context, requiring reloading — for example, by
- changing a bean definition or the state of an application object —
- you can annotate your test method with
- @DirtiesContext (assuming
+ 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) to cause the test fixture to reload
+ configured, which is the default). This instructs Spring to reload
the configurations and rebuild the application context before
- executing the next test.
+ executing the next test.
@@ -1119,12 +1122,10 @@ public class ExtendedTest extends BaseTest {
When you configure the
DependencyInjectionTestExecutionListener —
- which is configured by default through the
- @TestExecutionListeners annotation —
- the dependencies of your test instances are
- injected from beans in the application context
- you configured through
- @ContextConfiguration by setter
+ which is configured by default — the dependencies of your
+ test instances are injected from beans in the
+ application context that you configured with
+ @ContextConfiguration. You may use setter
injection, field injection, or both, depending on which annotations
you choose and whether you place them on setter methods or fields. For
consistency with the annotation support introduced in Spring 2.5, you
@@ -1155,7 +1156,7 @@ public class ExtendedTest extends BaseTest {
name. Alternatively, if your test class has access to its
ApplicationContext, you can perform an explicit
lookup by using (for example) a call to
- applicationContext.getBean("titleDao"). A
+ applicationContext.getBean("titleRepository"). A
third option is to use @Autowired in
conjunction with @Qualifier.
@@ -1169,13 +1170,13 @@ public class ExtendedTest extends BaseTest {
DependencyInjectionTestExecutionListener.class from
the list of listeners.
- Consider the scenario of a class,
- HibernateTitleDao, as outlined in the Goals section. (We will look at
- the application context configuration after all sample code listings.)
- A JUnit 4-based implementation of the test class itself uses
- @Autowired for field injection.
-
+ Consider the scenario of testing a
+ HibernateTitleRepository class, as outlined in the Goals section. The next four
+ code listings demonstrate the use of @Autowired
+ and @Resource on fields and
+ setter methods. The application context configuration is presented
+ after all sample code listings.The dependency injection behavior in the following code
@@ -1191,90 +1192,99 @@ public class ExtendedTest extends BaseTest {
example.
+ The first code listing shows a JUnit 4-based implementation
+ of the test class that uses @Autowired
+ for field injection.
+
@RunWith(SpringJUnit4ClassRunner.class)
// specifies the Spring configuration to load for this test fixture
-@ContextConfiguration("daos.xml")
-public final class HibernateTitleDaoTests {
+@ContextConfiguration("repository-config.xml")
+public class HibernateTitleRepositoryTests {
// this instance will be dependency injected by type@Autowired
- private HibernateTitleDao titleDao;
+ private HibernateTitleRepository titleRepository;
- public void testLoadTitle() throws Exception {
- Title title = this.titleDao.loadTitle(new Long(10));
+ @Test
+ public void loadTitle() {
+ Title title = titleRepository.loadTitle(new Long(10));
assertNotNull(title);
}
}Alternatively, you can configure the class to use
- @Autowired for setter injection.
+ @Autowired for setter injection as
+ seen below.
@RunWith(SpringJUnit4ClassRunner.class)
// specifies the Spring configuration to load for this test fixture
-@ContextConfiguration("daos.xml")
-public final class HibernateTitleDaoTests {
+@ContextConfiguration("repository-config.xml")
+public class HibernateTitleRepositoryTests {
// this instance will be dependency injected by type
- private HibernateTitleDao titleDao;
+ private HibernateTitleRepository titleRepository;
@Autowired
- public void setTitleDao(HibernateTitleDao titleDao) {
- this.titleDao = titleDao;
+ public void setTitleRepository(HibernateTitleRepository titleRepository) {
+ this.titleRepository = titleRepository;
}
- public void testLoadTitle() throws Exception {
- Title title = this.titleDao.loadTitle(new Long(10));
+ @Test
+ public void loadTitle() {
+ Title title = titleRepository.loadTitle(new Long(10));
assertNotNull(title);
}
}
- Here is an example of @Resource
+ The following is an example of using @Resource
for field injection.@RunWith(SpringJUnit4ClassRunner.class)
// specifies the Spring configuration to load for this test fixture
-@ContextConfiguration("daos.xml")
-public final class HibernateTitleDaoTests {
+@ContextConfiguration("repository-config.xml")
+public class HibernateTitleRepositoryTests {
// this instance will be dependency injected by name@Resource
- private HibernateTitleDao titleDao;
+ private HibernateTitleRepository titleRepository;
- public void testLoadTitle() throws Exception {
- Title title = this.titleDao.loadTitle(new Long(10));
+ @Test
+ public void loadTitle() {
+ Title title = titleRepository.loadTitle(new Long(10));
assertNotNull(title);
}
}
- Here is an example of @Resource
+ Here is an example of using @Resource
for setter injection.@RunWith(SpringJUnit4ClassRunner.class)
// specifies the Spring configuration to load for this test fixture
-@ContextConfiguration("daos.xml")
-public final class HibernateTitleDaoTests {
+@ContextConfiguration("repository-config.xml")
+public class HibernateTitleRepositoryTests {
// this instance will be dependency injected by name
- private HibernateTitleDao titleDao;
+ private HibernateTitleRepository titleRepository;
@Resource
- public void setTitleDao(HibernateTitleDao titleDao) {
- this.titleDao = titleDao;
+ public void setTitleRepository(HibernateTitleRepository titleRepository) {
+ this.titleRepository = titleRepository;
}
- public void testLoadTitle() throws Exception {
- Title title = this.titleDao.loadTitle(new Long(10));
+ @Test
+ public void loadTitle() {
+ Title title = titleRepository.loadTitle(new Long(10));
assertNotNull(title);
}
}The preceding code listings use the same XML context file
referenced by the @ContextConfiguration
- annotation (that is, daos.xml), which looks like
+ annotation (that is, repository-config.xml), which looks like
this:<?xml version="1.0" encoding="UTF-8"?>
@@ -1283,15 +1293,15 @@ public final class HibernateTitleDaoTests {
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
- <!-- this bean will be injected into the HibernateTitleDaoTests class -->
- <bean id="titleDao" class="com.foo.dao.hibernate.HibernateTitleDao">
+ <!-- this bean will be injected into the HibernateTitleRepositoryTests class -->
+ <bean id="titleRepository" class="com.foo.repository.hibernate.HibernateTitleRepository">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- <!-- dependencies elided for clarity -->
+ <!-- configuration elided for brevity -->
</bean>
</beans>
@@ -1302,9 +1312,10 @@ public final class HibernateTitleDaoTests {
of its setter methods, you might have multiple beans of the affected
type defined in your application context: for example, multiple
DataSource beans. In such a case, you
- can override the setter and use the
+ can override the setter method and use the
@Qualifier annotation to indicate a
- specific target bean as follows:
+ specific target bean as follows, but make sure to delegate to the
+ overridden method in the superclass as well.// ...
@@ -1323,19 +1334,18 @@ public final class HibernateTitleDaoTests {
corresponding <bean> definitions. The bean
name is used as a fallback qualifier value, so you may effectively
also point to a specific bean by name there (as shown above,
- assuming that "myDataSource" is the bean id). If there is only one
- DataSource bean to begin with, then
- the qualifier does not have any effect, independent from the bean
- name of that single matching bean.
-
+ assuming that "myDataSource" is the bean id).
Alternatively, consider using the
@Resource annotation on such
- overridden setter methods, defining the target bean name explicitly,
- with no type matching semantics. Note that this
- always
- points to a bean with that specific name, no matter whether there is
- one or more beans of the given type.
+ overridden setter methods. This allows you to specify the name of
+ the target bean explicitly, but without type matching semantics.
+ In contrast to the solution above that combined
+ @Autowired and
+ @Qualifier, using
+ @Resource results in the
+ selection of a bean with that specific name, regardless of
+ how many beans of the given type exist in the context.
// ...
@@ -1353,10 +1363,9 @@ public final class HibernateTitleDaoTests {
Transaction managementIn the TestContext framework, transactions are managed by the
- TransactionalTestExecutionListener, which is
- configured through the
- @TestExecutionListeners annotation by
- default, even if you do not explicitly declare
+ TransactionalTestExecutionListener. Note that
+ TransactionalTestExecutionListener is
+ configured by default, even if you do not explicitly declare
@TestExecutionListeners on your test
class. To enable support for transactions, however, you must provide a
PlatformTransactionManager bean in the
@@ -1364,9 +1373,9 @@ public final class HibernateTitleDaoTests {
@ContextConfiguration semantics. In
addition, you must declare
@Transactional either at the class or
- method level.
+ method level for your tests.
- For class-level transaction configuration (that is, setting the
+ For class-level transaction configuration (i.e., setting the
bean name for the transaction manager and the default rollback flag),
see the @TransactionConfiguration entry
in the annotation
@@ -1392,7 +1401,7 @@ public final class HibernateTitleDaoTests {
transactional test method but outside the transactional context, for
example, to verify the initial database state prior to execution of
your test or to verify expected transactional commit behavior after
- test execution (for example, if the test was configured not to roll
+ test execution (if the test was configured not to roll
back the transaction).
TransactionalTestExecutionListener supports the
@BeforeTransaction and
@@ -1405,7 +1414,7 @@ public final class HibernateTitleDaoTests {
time.
- Any before methods (for example, methods
+ Any before methods (e.g., methods
annotated with JUnit 4's @Before) and any after
methods (such as methods annotated with JUnit 4's @After)
are executed within a transaction.
@@ -1422,9 +1431,7 @@ public final class HibernateTitleDaoTests {
integration testing scenario highlighting several transaction-related
annotations. Consult the annotation support
- section of the reference manual
- for
- further information and configuration examples.
+ section for further information and configuration examples.@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@@ -1465,19 +1472,17 @@ public class FictitiousTransactionalTest {
Avoid false positives when testing ORM code
- When you test code involving an ORM framework such as JPA or
- Hibernate, flush the underlying session within
- test methods
- which update the state of the
- session. Failing to flush the ORM framework's underlying session can
+ When you test application code that manipulates the state of
+ the Hibernate session, make sure to flush the
+ underlying session within test methods that execute that code.
+ Failing to flush the underlying session can
produce false positives: your test may pass,
but the same code throws an exception in a live, production
environment. In the following Hibernate-based example test case, one
- method demonstrates a false positive and the other method correctly
- exposes the results of flushing the session.
+ method demonstrates a false positive, and the other method correctly
+ exposes the results of flushing the session. Note that this
+ applies to JPA and any other ORM frameworks that maintain an
+ in-memory unit of work.// ...
@@ -1518,20 +1523,16 @@ public void updateWithSessionFlush() {
Abstract TestCase that integrates the
Spring TestContext Framework with explicit
ApplicationContext testing support in a
- JUnit 3.8 environment. When you extend the
- AbstractJUnit38SpringContextTests class,
- you need access to the following protected
- instance variables:
-
+ JUnit 3.8 environment. When you extend
+ AbstractJUnit38SpringContextTests,
+ you can access the following protected
+ instance variable:
- applicationContext: Perform
- explicit bean lookups or test the state of the context as a
+ applicationContext:
+ Use this variable to perform explicit bean
+ lookups or to test the state of the context as a
whole.
@@ -1545,9 +1546,9 @@ public void updateWithSessionFlush() {
Expects a javax.sql.DataSource bean and a
PlatformTransactionManager bean
to be defined in the ApplicationContext.
- When you extend the
- AbstractTransactionalJUnit38SpringContextTests
- class, you will have access to the following
+ When you extend
+ AbstractTransactionalJUnit38SpringContextTests,
+ you can access the following
protected instance variables:
@@ -1597,8 +1598,9 @@ public void updateWithSessionFlush() {
- applicationContext: Perform
- explicit bean lookups or test the state of the context as a
+ applicationContext:
+ Use this variable to perform explicit bean
+ lookups or to test the state of the context as a
whole.
@@ -1644,7 +1646,7 @@ public void updateWithSessionFlush() {
These classes are a convenience for extension. If you do not
want your test classes to be tied to a Spring-specific class
- hierarchy — for example, if you want to extend directly the class
+ hierarchy — for example, if you want to directly extend the class
you are testing — you can configure your own custom test classes
by using
@RunWith(SpringJUnit4ClassRunner.class),
@@ -1659,7 +1661,7 @@ public void updateWithSessionFlush() {
The Spring TestContext Framework offers
full integration with JUnit 4.5+ through a custom runner (tested on
- JUnit 4.5, 4.6, and 4.7). By annotating test classes with
+ JUnit 4.5 – 4.8). By annotating test classes with
@RunWith(SpringJUnit4ClassRunner.class),
developers can implement standard JUnit 4.5+ unit and integration
tests and simultaneously reap the benefits of the TestContext
@@ -1698,14 +1700,15 @@ public class SimpleTest {
TestNG environment.When you extend
- AbstractTestNGSpringContextTests you can
+ AbstractTestNGSpringContextTests, you can
access the following protected instance
variable:
- applicationContext: Perform
- explicit bean lookups or test the state of the context as a
+ applicationContext:
+ Use this variable to perform explicit bean
+ lookups or to test the state of the context as a
whole.
@@ -1720,7 +1723,7 @@ public class SimpleTest {
PlatformTransactionManager bean
to be defined in the ApplicationContext.
When you extend
- AbstractTransactionalTestNGSpringContextTests,
+ AbstractTransactionalTestNGSpringContextTests,
you can access the following protected
instance variables:
@@ -1767,7 +1770,8 @@ public class SimpleTest {
PetClinic example
- The PetClinic application, available from the samples repository,
+ The PetClinic application, available from the
+ samples repository,
illustrates several features of the Spring
TestContext Framework in a JUnit 4.5+ environment. Most test
functionality is included in the
@@ -1821,7 +1825,7 @@ public abstract class AbstractClinicTests extends Abstract
The testGetVets() method illustrates
how you can use the inherited
countRowsInTable() method to easily verify
- the number of rows in a given table, thus testing correct behavior
+ the number of rows in a given table, thus verifying correct behavior
of the application code being tested. This allows for stronger tests
and lessens dependency on the exact test data. For example, you can
add additional rows in the database without breaking tests.
@@ -1831,9 +1835,9 @@ public abstract class AbstractClinicTests extends Abstract
Like many integration tests that use a database, most of the
tests in AbstractClinicTests depend on a
minimum amount of data already in the database before the test cases
- run. You might, however, choose to populate the database in
- your
- test cases also — again, within the same transaction.
+ run. Alternatively, you might choose to populate the database within
+ the test fixture set up of your test cases — again,
+ within the same transaction as the tests.
@@ -1858,7 +1862,7 @@ public abstract class AbstractClinicTests extends Abstract
@ContextConfiguration is declared without
any specific resource locations, the Spring TestContext
Framework loads an application context from all the beans
- defined in AbstractClinicTests-context.xml (that is,
+ defined in AbstractClinicTests-context.xml (i.e.,
the inherited locations) and
HibernateClinicTests-context.xml, with
HibernateClinicTests-context.xml possibly overriding
@@ -1869,13 +1873,12 @@ public abstract class AbstractClinicTests extends Abstract
public class HibernateClinicTests extends AbstractClinicTests { }
- As you can see in the PetClinic application, the Spring
- configuration is split across multiple files. As
- is typical of large-scale applications, configuration locations are
- often specified in a common base class for all application-specific
+ In a large-scale application, the Spring configuration is
+ often split across multiple files. Consequently, configuration locations
+ are typically specified in a common base class for all application-specific
integration tests. Such a base class may also add useful instance
variables — populated by Dependency Injection, naturally — such as a
- HibernateTemplate, in the case of an application
+ SessionFactory in the case of an application
using Hibernate.As far as possible, you should have exactly the same Spring
@@ -1884,7 +1887,7 @@ public class HibernateClinicTests extends AbstractClinicTests { }
pooling and transaction infrastructure. If you are deploying to a
full-blown application server, you will probably use its connection pool
(available through JNDI) and JTA implementation. Thus in production you
- will use a JndiObjectFactoryBean /
+ will use a JndiObjectFactoryBean or
<jee:jndi-lookup> for the
DataSource and
JtaTransactionManager. JNDI and JTA will not be
@@ -1896,7 +1899,7 @@ public class HibernateClinicTests extends AbstractClinicTests { }
choice between application server and a 'local' configuration separated
from all other configuration, which will not vary between the test and
production environments. In addition, it is advisable to use properties
- files for connection settings: see the PetClinic application for an
+ files for connection settings. See the PetClinic application for an
example.
@@ -1909,9 +1912,9 @@ public class HibernateClinicTests extends AbstractClinicTests { }
- JUnit: The Spring
- Framework's unit and integration test suite, written with JUnit 3.8.2
- and JUnit 4.7 as the testing framework.
+ JUnit:
+ A programmer-oriented testing framework for Java.
+ Used by the Spring Framework in its test suite.
@@ -1935,7 +1938,7 @@ public class HibernateClinicTests extends AbstractClinicTests { }
EasyMock: Used
- extensively by the Spring Framework in its test suite.
+ by the Spring Framework in its test suite.