[SPR-8627] Deprecated @ExpectedException.

[SPR-8240] cleaned up and formatted the testing chapter.
This commit is contained in:
Sam Brannen 2011-08-26 22:21:16 +00:00
parent 0460a5eceb
commit 7908d05c71
1 changed files with 273 additions and 284 deletions

View File

@ -115,9 +115,9 @@
<para>The <literal>org.springframework.test.web</literal> package <para>The <literal>org.springframework.test.web</literal> package
contains <classname>ModelAndViewAssert</classname>, which you can use contains <classname>ModelAndViewAssert</classname>, which you can use
in combination with JUnit, TestNG, or any other testing framework in combination with JUnit, TestNG, or any other testing framework for
for unit tests dealing unit tests dealing with Spring MVC <classname>ModelAndView</classname>
with Spring MVC <classname>ModelAndView</classname> objects.</para> objects.</para>
<tip> <tip>
<title>Unit testing Spring MVC Controllers</title> <title>Unit testing Spring MVC Controllers</title>
@ -157,22 +157,19 @@
</listitem> </listitem>
</itemizedlist> </itemizedlist>
<para>The Spring Framework provides first-class support for <para>The Spring Framework provides first-class support for integration
integration testing in testing in the <filename class="libraryfile">spring-test</filename>
the <filename class="libraryfile">spring-test</filename> module. 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
version and might also be in the <filename>org.springframework.test</filename> form, depending on where
long <filename>org.springframework.test</filename> form, you get it from (see the <link linkend="dependency-management">section
depending on where you got it from (see on Dependency Management</link> for an explanation). This library
the <link linkend="dependency-management"> section on Dependency includes the <literal>org.springframework.test</literal> package, which
Management</link> for an explanation). This library includes
the <literal>org.springframework.test</literal> package, which
contains valuable classes for integration testing with a Spring contains valuable classes for integration testing with a Spring
container. This testing does not rely on an application server container. This testing does not rely on an application server or other
or other deployment environment. Such tests are slower to run deployment environment. Such tests are slower to run than unit tests but
than unit tests but much faster than the equivalent Cactus much faster than the equivalent Cactus tests or remote tests that rely
tests or remote tests that rely on deployment to an application on deployment to an application server.</para>
server.</para>
<para>In Spring 2.5 and later, unit and integration testing support is <para>In Spring 2.5 and later, unit and integration testing support is
provided in the form of the annotation-driven <link provided in the form of the annotation-driven <link
@ -184,50 +181,56 @@
<warning> <warning>
<title>JUnit 3.8 support is deprecated</title> <title>JUnit 3.8 support is deprecated</title>
<para>As of Spring 3.0, the legacy JUnit 3.8 base class hierarchy (i.e., <para>As of Spring 3.0, the legacy JUnit 3.8 base class hierarchy
(i.e.,
<classname>AbstractDependencyInjectionSpringContextTests</classname>, <classname>AbstractDependencyInjectionSpringContextTests</classname>,
<classname>AbstractTransactionalDataSourceSpringContextTests</classname>, <classname>AbstractTransactionalDataSourceSpringContextTests</classname>,
etc.) is officially deprecated and will be removed in a later release. etc.) is officially deprecated and will be removed in a later release.
Any test classes based on this code should be migrated to the Any test classes based on this code should be migrated to the <link
<link linkend="testcontext-framework">Spring linkend="testcontext-framework">Spring TestContext
TestContext Framework</link>.</para> Framework</link>.</para>
<para>As of Spring 3.1, the JUnit 3.8 base classes in the Spring <para>As of Spring 3.1, the JUnit 3.8 base classes in the Spring
TestContext Framework (i.e., TestContext Framework (i.e.,
<classname>AbstractJUnit38SpringContextTests</classname> and <classname>AbstractJUnit38SpringContextTests</classname> and
<classname>AbstractTransactionalJUnit38SpringContextTests</classname>) <classname>AbstractTransactionalJUnit38SpringContextTests</classname>)
have been officially deprecated and will be removed in a later release. and <interfacename>@ExpectedException</interfacename> have been
Any test classes based on this code should be migrated to the JUnit 4 officially deprecated and will be removed in a later release. Any test
or TestNG support provided by the <link linkend="testcontext-framework">Spring classes based on this code should be migrated to the JUnit 4 or TestNG
TestContext Framework</link>.</para> support provided by the <link linkend="testcontext-framework">Spring
TestContext Framework</link>. Similarly, any test methods annotated
with <interfacename>@ExpectedException</interfacename> should be
modified to use the built-in support for expected exceptions in JUnit
and TestNG.</para>
</warning> </warning>
</section> </section>
<section id="integration-testing-goals"> <section id="integration-testing-goals">
<title>Goals of integration testing</title> <title>Goals of integration testing</title>
<para>Spring's integration testing support has the following <para>Spring's integration testing support has the following primary
primary goals:</para> goals:</para>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para>To manage <link linkend="testing-ctx-management">Spring IoC container <para>To manage <link linkend="testing-ctx-management">Spring IoC
caching</link> between test execution.</para> container caching</link> between test execution.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>To provide <link linkend="testing-fixture-di">Dependency Injection of <para>To provide <link linkend="testing-fixture-di">Dependency
test fixture instances</link>.</para> Injection of test fixture instances</link>.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>To provide <link linkend="testing-tx">transaction management</link> <para>To provide <link linkend="testing-tx">transaction
appropriate to integration testing.</para> management</link> appropriate to integration testing.</para>
</listitem> </listitem>
<listitem> <listitem>
<para>To supply <link linkend="testing-support-classes">Spring-specific <para>To supply <link
base classes</link> that assist developers in writing integration linkend="testing-support-classes">Spring-specific base
classes</link> that assist developers in writing integration
tests.</para> tests.</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@ -241,7 +244,7 @@
<para>The Spring TestContext Framework provides consistent loading of <para>The Spring TestContext Framework provides consistent loading of
Spring <classname>ApplicationContext</classname>s and caching of those Spring <classname>ApplicationContext</classname>s and caching of those
contexts. Support for the caching of loaded contexts is important, contexts. Support for the caching of loaded contexts is important,
because startup time can become an issue &mdash; not because of the overhead because startup time can become an issue not because of the overhead
of Spring itself, but because the objects instantiated by the Spring of Spring itself, but because the objects instantiated by the Spring
container take time to instantiate. For example, a project with 50 to container take time to instantiate. For example, a project with 50 to
100 Hibernate mapping files might take 10 to 20 seconds to load the 100 Hibernate mapping files might take 10 to 20 seconds to load the
@ -249,8 +252,10 @@
every test fixture leads to slower overall test runs that could reduce every test fixture leads to slower overall test runs that could reduce
productivity.</para> productivity.</para>
<!--TODO Modify the following paragraph regarding 3.1's support for @Configuration classes.-->
<para>Test classes provide an array containing the resource locations <para>Test classes provide an array containing the resource locations
of XML configuration metadata &mdash; typically in the classpath &mdash; that is of XML configuration metadata — typically in the classpath — that is
used to configure the application. These locations are the same as or used to configure the application. These locations are the same as or
similar to the list of configuration locations specified in similar to the list of configuration locations specified in
<literal>web.xml</literal> or other deployment configuration <literal>web.xml</literal> or other deployment configuration
@ -258,13 +263,13 @@
<para>By default, once loaded, the configured <para>By default, once loaded, the configured
<interfacename>ApplicationContext</interfacename> is reused for each <interfacename>ApplicationContext</interfacename> is reused for each
test. Thus the setup cost is incurred only once (per test suite), test. Thus the setup cost is incurred only once (per test suite), and
and subsequent test execution is much faster. In the unlikely case subsequent test execution is much faster. In the unlikely case that a
that a test corrupts the application context and requires reloading &mdash; test corrupts the application context and requires reloading — for
for example, by modifying a bean definition or the state of an example, by modifying a bean definition or the state of an application
application object &mdash; the TestContext framework can be configured object — the TestContext framework can be configured to reload the
to reload the configuration and rebuild the application configuration and rebuild the application context before executing the
context before executing the next test.</para> next test.</para>
<para>See context management and caching with the <link <para>See context management and caching with the <link
linkend="testcontext-ctx-management">TestContext linkend="testcontext-ctx-management">TestContext
@ -282,12 +287,13 @@
contexts across various testing scenarios (e.g., for configuring contexts across various testing scenarios (e.g., for configuring
Spring-managed object graphs, transactional proxies, Spring-managed object graphs, transactional proxies,
<classname>DataSource</classname>s, etc.), thus avoiding the need to <classname>DataSource</classname>s, etc.), thus avoiding the need to
duplicate complex test fixture set up for individual test cases.</para> duplicate complex test fixture set up for individual test
cases.</para>
<para>As an example, consider the scenario where we have a class, <para>As an example, consider the scenario where we have a class,
<classname>HibernateTitleRepository</classname>, that performs data access <classname>HibernateTitleRepository</classname>, that performs data
logic for say, the <classname>Title</classname> domain object. We want access logic for say, the <classname>Title</classname> domain object.
to write integration tests that test all of the following We want to write integration tests that test all of the following
areas:</para> areas:</para>
<itemizedlist> <itemizedlist>
@ -305,9 +311,9 @@
</listitem> </listitem>
<listitem> <listitem>
<para>The logic of the <classname>HibernateTitleRepository</classname>: <para>The logic of the
does the configured instance of this class perform as <classname>HibernateTitleRepository</classname>: does the
anticipated?</para> configured instance of this class perform as anticipated?</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@ -321,8 +327,8 @@
<para>One common issue in tests that access a real database is their <para>One common issue in tests that access a real database is their
affect on the state of the persistence store. Even when you're using a affect on the state of the persistence store. Even when you're using a
development database, changes to the state may affect future tests. development database, changes to the state may affect future tests.
Also, many operations &mdash; such as inserting or modifying persistent data Also, many operations such as inserting or modifying persistent data
&mdash; cannot be performed (or verified) outside a transaction.</para> cannot be performed (or verified) outside a transaction.</para>
<para>The TestContext framework addresses this issue. By default, the <para>The TestContext framework addresses this issue. By default, the
framework will create and roll back a transaction for each test. You framework will create and roll back a transaction for each test. You
@ -336,9 +342,9 @@
a <classname>PlatformTransactionManager</classname> bean defined in a <classname>PlatformTransactionManager</classname> bean defined in
the test's application context.</para> the test's application context.</para>
<para>If you want a transaction to commit &mdash; unusual, but occasionally <para>If you want a transaction to commit unusual, but occasionally
useful when you want a particular test to populate or modify the useful when you want a particular test to populate or modify the
database &mdash; the TestContext framework can be instructed to cause the database the TestContext framework can be instructed to cause the
transaction to commit instead of roll back via the <link transaction to commit instead of roll back via the <link
linkend="integration-testing-annotations"><interfacename>@TransactionConfiguration</interfacename></link> linkend="integration-testing-annotations"><interfacename>@TransactionConfiguration</interfacename></link>
and <link and <link
@ -367,14 +373,14 @@
<listitem> <listitem>
<para>A <classname>SimpleJdbcTemplate</classname>, for executing <para>A <classname>SimpleJdbcTemplate</classname>, for executing
SQL statements to query the database. SQL statements to query the database. Such queries can be used to
Such queries can be used to confirm database state both confirm database state both <emphasis>prior to</emphasis> and
<emphasis>prior to</emphasis> and <emphasis>after</emphasis> <emphasis>after</emphasis> execution of database-related
execution of database-related application code, and Spring application code, and Spring ensures that such queries run in the
ensures that such queries run in the scope of the same scope of the same transaction as the application code. When used
transaction as the application code. When used in conjunction in conjunction with an ORM tool, be sure to avoid <link
with an ORM tool, be sure to avoid linkend="testcontext-tx-false-positives">false
<link linkend="testcontext-tx-false-positives">false positives</link>.</para> positives</link>.</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@ -408,7 +414,7 @@
<para>The Spring Framework provides the following set of <para>The Spring Framework provides the following set of
<emphasis>Spring-specific</emphasis> annotations that you can use in <emphasis>Spring-specific</emphasis> annotations that you can use in
your unit and integration tests in conjunction with the TestContext your unit and integration tests in conjunction with the TestContext
framework. Refer to the respective JavaDoc for further information, framework. Refer to the respective Javadoc for further information,
including default attribute values, attribute aliases, and so on.</para> including default attribute values, attribute aliases, and so on.</para>
<itemizedlist> <itemizedlist>
@ -422,7 +428,10 @@
<interfacename>@ContextConfiguration</interfacename> defines the <interfacename>@ContextConfiguration</interfacename> defines the
application context resource <literal>locations</literal> to load as application context resource <literal>locations</literal> to load as
well as the <interfacename>ContextLoader</interfacename> strategy to well as the <interfacename>ContextLoader</interfacename> strategy to
use for loading the context.</para> use for loading the context. Note, however, that you typically do
not need to explicitly configure the loader since the default loader
supports either resource <varname>locations</varname> or
configuration <varname>classes</varname>.</para>
<programlisting language="java">@ContextConfiguration(locations="example/test-context.xml", loader=CustomContextLoader.class) <programlisting language="java">@ContextConfiguration(locations="example/test-context.xml", loader=CustomContextLoader.class)
public class CustomConfiguredApplicationContextTests { public class CustomConfiguredApplicationContextTests {
@ -433,7 +442,7 @@ public class CustomConfiguredApplicationContextTests {
<para><interfacename>@ContextConfiguration</interfacename> <para><interfacename>@ContextConfiguration</interfacename>
supports <emphasis>inherited</emphasis> resource locations by supports <emphasis>inherited</emphasis> resource locations by
default. See <link linkend="testcontext-ctx-management">Context default. See <link linkend="testcontext-ctx-management">Context
management and caching</link> and JavaDoc for an example and management and caching</link> and Javadoc for an example and
further details.</para> further details.</para>
</note> </note>
</listitem> </listitem>
@ -444,11 +453,11 @@ public class CustomConfiguredApplicationContextTests {
<para>Indicates that the underlying Spring <para>Indicates that the underlying Spring
<interfacename>ApplicationContext</interfacename> has been <interfacename>ApplicationContext</interfacename> has been
<emphasis>dirtied</emphasis> (i.e., modified or corrupted in some manner) <emphasis>dirtied</emphasis> (i.e., modified or corrupted in some
during the execution of a test and should be closed, manner) during the execution of a test and should be closed,
regardless of whether the test passed. regardless of whether the test passed.
<interfacename>@DirtiesContext</interfacename> is supported in <interfacename>@DirtiesContext</interfacename> is supported in the
the following scenarios:</para> following scenarios:</para>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
@ -474,12 +483,13 @@ public class CustomConfiguredApplicationContextTests {
<para>With JUnit 4.5+ or TestNG you can use <para>With JUnit 4.5+ or TestNG you can use
<interfacename>@DirtiesContext</interfacename> as both a class-level <interfacename>@DirtiesContext</interfacename> as both a class-level
and method-level annotation within the same test class. In such scenarios, and method-level annotation within the same test class. In such
the <interfacename>ApplicationContext</interfacename> is marked as scenarios, the <interfacename>ApplicationContext</interfacename> is
<emphasis>dirty</emphasis> after any such annotated method as well marked as <emphasis>dirty</emphasis> after any such annotated method
as after the entire class. If the <classname>ClassMode</classname> as well as after the entire class. If the
is set to <literal>AFTER_EACH_TEST_METHOD</literal>, the context is <classname>ClassMode</classname> is set to
marked dirty after each test method in the class.</para> <literal>AFTER_EACH_TEST_METHOD</literal>, the context is marked
dirty after each test method in the class.</para>
<programlisting language="java">@DirtiesContext <programlisting language="java">@DirtiesContext
public class ContextDirtyingTests { public class ContextDirtyingTests {
@ -511,8 +521,8 @@ public void testProcessWhichDirtiesAppCtx() {
<para>Defines class-level metadata for configuring which <para>Defines class-level metadata for configuring which
<interfacename>TestExecutionListener</interfacename>s should be <interfacename>TestExecutionListener</interfacename>s should be
registered with the <classname>TestContextManager</classname>. registered with the <classname>TestContextManager</classname>.
Typically, <interfacename>@TestExecutionListeners</interfacename> Typically, <interfacename>@TestExecutionListeners</interfacename> is
is used in conjunction with used in conjunction with
<interfacename>@ContextConfiguration</interfacename>.</para> <interfacename>@ContextConfiguration</interfacename>.</para>
<programlisting language="java">@ContextConfiguration <programlisting language="java">@ContextConfiguration
@ -523,7 +533,7 @@ public class CustomTestExecutionListenerTests {
<para><interfacename>@TestExecutionListeners</interfacename> <para><interfacename>@TestExecutionListeners</interfacename>
supports <emphasis>inherited</emphasis> listeners by default. See supports <emphasis>inherited</emphasis> listeners by default. See
the JavaDoc for an example and further details.</para> the Javadoc for an example and further details.</para>
</listitem> </listitem>
<listitem> <listitem>
@ -534,8 +544,9 @@ public class CustomTestExecutionListenerTests {
tests. Specifically, the bean name of the tests. Specifically, the bean name of the
<interfacename>PlatformTransactionManager</interfacename> that is to <interfacename>PlatformTransactionManager</interfacename> that is to
be used to drive transactions can be explicitly configured if the be used to drive transactions can be explicitly configured if the
bean name of the desired <interfacename>PlatformTransactionManager</interfacename> bean name of the desired
is not "transactionManager". In addition, you can change the <interfacename>PlatformTransactionManager</interfacename> is not
"transactionManager". In addition, you can change the
<literal>defaultRollback</literal> flag to <literal>false</literal>. <literal>defaultRollback</literal> flag to <literal>false</literal>.
Typically, <interfacename>@TransactionConfiguration</interfacename> Typically, <interfacename>@TransactionConfiguration</interfacename>
is used in conjunction with is used in conjunction with
@ -548,13 +559,13 @@ public class CustomConfiguredTransactionalTests {
}</programlisting> }</programlisting>
<note> <note>
<para>If the default conventions are sufficient for your <para>If the default conventions are sufficient for your test
test configuration, you can avoid using configuration, you can avoid using
<interfacename>@TransactionConfiguration</interfacename> <interfacename>@TransactionConfiguration</interfacename>
altogether. In other words, if your transaction altogether. In other words, if your transaction manager bean is
manager bean is named "transactionManager" and if you want named "transactionManager" and if you want transactions to roll
transactions to roll back automatically, there is no need back automatically, there is no need to annotate your test class
to annotate your test class with with
<interfacename>@TransactionConfiguration</interfacename>.</para> <interfacename>@TransactionConfiguration</interfacename>.</para>
</note> </note>
</listitem> </listitem>
@ -646,9 +657,8 @@ public void testProcessWithoutTransaction() {
<para>The following annotations are <emphasis>only</emphasis> supported <para>The following annotations are <emphasis>only</emphasis> supported
when used in conjunction with the <link when used in conjunction with the <link
linkend="testcontext-junit4-runner">SpringJUnit4ClassRunner</link> or linkend="testcontext-junit4-runner">SpringJUnit4ClassRunner</link> or
the <link the <link linkend="testcontext-support-classes-junit4">JUnit</link>
linkend="testcontext-support-classes-junit4">JUnit</link> support support classes.</para>
classes.</para>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
@ -701,31 +711,6 @@ public class CustomProfileValueSourceTests {
}</programlisting> }</programlisting>
</listitem> </listitem>
<listitem>
<para><emphasis
role="bold"><interfacename>@ExpectedException</interfacename></emphasis></para>
<para>Indicates that the annotated test method is expected to throw
an exception during execution. The type of the expected exception is
provided in the annotation, and if an instance of the exception is
thrown during the test method execution then the test passes.
Likewise if an instance of the exception is <emphasis>not</emphasis>
thrown during the test method execution then the test fails.</para>
<programlisting language="java">@ExpectedException(SomeBusinessException.class)
public void testProcessRainyDayScenario() {
<lineannotation>// some logic that should result in an <classname>Exception</classname> being thrown</lineannotation>
}</programlisting>
<para>Using Spring's
<interfacename>@ExpectedException</interfacename> annotation in
conjunction with JUnit's
<interfacename>@Test(expected=...)</interfacename> configuration
would lead to an unresolvable conflict. Developers must therefore
choose one or the other when integrating with JUnit, in which case
it is generally preferable to use the explicit JUnit configuration.</para>
</listitem>
<listitem> <listitem>
<para><emphasis <para><emphasis
role="bold"><interfacename>@Timed</interfacename></emphasis></para> role="bold"><interfacename>@Timed</interfacename></emphasis></para>
@ -844,19 +829,19 @@ public void testProcessRepeatedly() {
Framework</emphasis> (located in the Framework</emphasis> (located in the
<literal>org.springframework.test.context</literal> package) provides <literal>org.springframework.test.context</literal> package) provides
generic, annotation-driven unit and integration testing support that is generic, annotation-driven unit and integration testing support that is
agnostic of the testing framework in use, whether JUnit or TestNG. agnostic of the testing framework in use, whether JUnit or TestNG. The
The TestContext framework also places a TestContext framework also places a great deal of importance on
great deal of importance on <emphasis>convention over <emphasis>convention over configuration</emphasis> with reasonable
configuration</emphasis> with reasonable defaults that can be overridden defaults that can be overridden through annotation-based
through annotation-based configuration.</para> configuration.</para>
<para>In addition to generic testing infrastructure, the TestContext <para>In addition to generic testing infrastructure, the TestContext
framework provides explicit support for JUnit and TestNG in the framework provides explicit support for JUnit and TestNG in the form of
form of <literal>abstract</literal> support classes. <literal>abstract</literal> support classes. For JUnit, Spring also
For JUnit, Spring also provides a custom JUnit provides a custom JUnit <interfacename>Runner</interfacename> that
<interfacename>Runner</interfacename> that allows one to write allows one to write so called <emphasis>POJO test classes</emphasis>.
so called <emphasis>POJO test classes</emphasis>. POJO test classes POJO test classes are not required to extend a particular class
are not required to extend a particular class hierarchy.</para> hierarchy.</para>
<para>The following section provides an overview of the internals of the <para>The following section provides an overview of the internals of the
TestContext framework. If you are only interested in using the framework TestContext framework. If you are only interested in using the framework
@ -884,7 +869,7 @@ public void testProcessRepeatedly() {
test progresses and delegates to test progresses and delegates to
<interfacename>TestExecutionListener</interfacename>s, which <interfacename>TestExecutionListener</interfacename>s, which
instrument the actual test execution, by providing dependency instrument the actual test execution, by providing dependency
injection, managing transactions, and so on. Consult the JavaDoc and injection, managing transactions, and so on. Consult the Javadoc and
the Spring test suite for further information and examples of various the Spring test suite for further information and examples of various
configurations.</para> configurations.</para>
@ -892,7 +877,8 @@ public void testProcessRepeatedly() {
<listitem> <listitem>
<para><classname>TestContext</classname>: Encapsulates the context <para><classname>TestContext</classname>: Encapsulates the context
in which a test is executed, agnostic of the actual testing in which a test is executed, agnostic of the actual testing
framework in use.</para> framework in use, and provides context management and caching
support for the test instance for which it is responsible.</para>
</listitem> </listitem>
<listitem> <listitem>
@ -908,20 +894,24 @@ public void testProcessRepeatedly() {
<para>prior to any <emphasis>before class methods</emphasis> <para>prior to any <emphasis>before class methods</emphasis>
of a particular testing framework</para> of a particular testing framework</para>
</listitem> </listitem>
<listitem> <listitem>
<para>test instance preparation</para> <para>test instance preparation</para>
</listitem> </listitem>
<listitem> <listitem>
<para>prior to any <emphasis>before methods</emphasis> <para>prior to any <emphasis>before methods</emphasis> of a
of a particular testing framework</para> particular testing framework</para>
</listitem> </listitem>
<listitem> <listitem>
<para>after any <emphasis>after methods</emphasis> <para>after any <emphasis>after methods</emphasis> of a
of a particular testing framework</para> particular testing framework</para>
</listitem> </listitem>
<listitem> <listitem>
<para>after any <emphasis>after class methods</emphasis> <para>after any <emphasis>after class methods</emphasis> of a
of a particular testing framework</para> particular testing framework</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</listitem> </listitem>
@ -942,7 +932,8 @@ public void testProcessRepeatedly() {
Respectively, they support dependency injection of the test Respectively, they support dependency injection of the test
instance, handling of the instance, handling of the
<interfacename>@DirtiesContext</interfacename> annotation, and <interfacename>@DirtiesContext</interfacename> annotation, and
transactional test execution with default rollback semantics.</para> transactional test execution with default rollback
semantics.</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@ -990,20 +981,20 @@ public class MyTest {
}</programlisting> }</programlisting>
</tip> </tip>
<para>In contrast to the deprecated JUnit 3.8 legacy class <para>In contrast to the deprecated JUnit 3.8 legacy class hierarchy,
hierarchy, test classes that use the TestContext framework do not need test classes that use the TestContext framework do not need to
to override any <literal>protected</literal> instance methods to override any <literal>protected</literal> instance methods to
configure their application context. Rather, configuration is achieved configure their application context. Rather, configuration is achieved
merely by declaring the merely by declaring the
<interfacename>@ContextConfiguration</interfacename> annotation at the <interfacename>@ContextConfiguration</interfacename> annotation at the
class level. If your test class does not explicitly declare class level. If your test class does not explicitly declare
application context resource <literal>locations</literal>, the application context resource <literal>locations</literal>, the
configured <interfacename>ContextLoader</interfacename> determines how configured <interfacename>ContextLoader</interfacename> determines how
and whether to load a context from a default location. For and whether to load a context from a default location. For example,
example, <classname>GenericXmlContextLoader</classname>, which is the <classname>GenericXmlContextLoader</classname>, which is the default
default <interfacename>ContextLoader</interfacename>, generates a <interfacename>ContextLoader</interfacename>, generates a default
default location based on the name of the test class. If your class is location based on the name of the test class. If your class is named
named <literal>com.example.MyTest</literal>, <literal>com.example.MyTest</literal>,
<classname>GenericXmlContextLoader</classname> loads your application <classname>GenericXmlContextLoader</classname> loads your application
context from context from
<literal>"classpath:/com/example/MyTest-context.xml"</literal>.</para> <literal>"classpath:/com/example/MyTest-context.xml"</literal>.</para>
@ -1022,16 +1013,16 @@ public class MyTest {
<interfacename>@ContextConfiguration</interfacename> with an array <interfacename>@ContextConfiguration</interfacename> with an array
that contains the resource locations of XML configuration metadata that contains the resource locations of XML configuration metadata
(assuming an XML-capable <interfacename>ContextLoader</interfacename> (assuming an XML-capable <interfacename>ContextLoader</interfacename>
has been configured, which is the default). A plain path, for has been configured, which is the default). A plain path, for example
example <literal>"context.xml"</literal>, will be treated as a <literal>"context.xml"</literal>, will be treated as a classpath
classpath resource from the same package in which the test class resource from the same package in which the test class is defined. A
is defined. A path starting with a slash is treated as a fully qualified path starting with a slash is treated as a fully qualified classpath
classpath location, for example <literal>"/org/example/config.xml"</literal>. location, for example <literal>"/org/example/config.xml"</literal>. A
A path which represents a URL (i.e., a path prefixed with path which represents a URL (i.e., a path prefixed with
<literal>classpath:</literal>, <literal>file:</literal>, <literal>classpath:</literal>, <literal>file:</literal>,
<literal>http:</literal>, etc.) will be used <emphasis>as is</emphasis>. <literal>http:</literal>, etc.) will be used <emphasis>as
Alternatively, you can implement and configure your own custom is</emphasis>. Alternatively, you can implement and configure your own
<interfacename>ContextLoader</interfacename>.</para> custom <interfacename>ContextLoader</interfacename>.</para>
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class) <programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
<lineannotation>// ApplicationContext will be loaded from <literal>"/applicationContext.xml"</literal> and <literal>"/applicationContext-test.xml"</literal></lineannotation> <lineannotation>// ApplicationContext will be loaded from <literal>"/applicationContext.xml"</literal> and <literal>"/applicationContext-test.xml"</literal></lineannotation>
@ -1049,10 +1040,9 @@ public class MyTest {
attribute name and declare the resource locations by using the attribute name and declare the resource locations by using the
shorthand format demonstrated in the following example.</para> shorthand format demonstrated in the following example.</para>
<para> <para><interfacename>@ContextConfiguration</interfacename> also
<interfacename>@ContextConfiguration</interfacename> also supports a supports a boolean <literal>inheritLocations</literal> attribute that
boolean <literal>inheritLocations</literal> attribute that denotes denotes whether resource locations from superclasses should be
whether resource locations from superclasses should be
<emphasis>inherited</emphasis>. The default value is <emphasis>inherited</emphasis>. The default value is
<literal>true</literal>, which means that an annotated class inherits <literal>true</literal>, which means that an annotated class inherits
the resource locations defined by an annotated superclass. the resource locations defined by an annotated superclass.
@ -1060,7 +1050,8 @@ public class MyTest {
appended to the list of resource locations defined by an annotated appended to the list of resource locations defined by an annotated
superclass. Thus, subclasses have the option of superclass. Thus, subclasses have the option of
<emphasis>extending</emphasis> the list of resource locations. In the <emphasis>extending</emphasis> the list of resource locations. In the
following example, the <interfacename>ApplicationContext</interfacename> for following example, the
<interfacename>ApplicationContext</interfacename> for
<classname>ExtendedTest</classname> is loaded from "/base-context.xml" <classname>ExtendedTest</classname> is loaded from "/base-context.xml"
<emphasis role="bold">and</emphasis> "/extended-context.xml", in that <emphasis role="bold">and</emphasis> "/extended-context.xml", in that
order. Beans defined in "/extended-context.xml" may therefore override order. Beans defined in "/extended-context.xml" may therefore override
@ -1082,38 +1073,38 @@ public class ExtendedTest extends BaseTest {
<para>If <literal>inheritLocations</literal> is set to <para>If <literal>inheritLocations</literal> is set to
<literal>false</literal>, the resource locations for the annotated <literal>false</literal>, the resource locations for the annotated
class shadow and effectively replace any resource locations defined class shadow and effectively replace any resource locations defined by
by a superclass.</para> a superclass.</para>
<para>By default, once loaded, the configured <para>By default, once loaded, the configured
<interfacename>ApplicationContext</interfacename> is reused for each <interfacename>ApplicationContext</interfacename> is reused for each
test. Thus the setup cost is incurred only once (per test suite), test. Thus the setup cost is incurred only once (per test suite), and
and subsequent test execution is much faster. In the unlikely case subsequent test execution is much faster. In the unlikely case that a
that a test corrupts the application context and requires reloading &mdash; test corrupts the application context and requires reloading — for
for example, by modifying a bean definition or the state of an example, by modifying a bean definition or the state of an application
application object &mdash; you can annotate your test class or test object — you can annotate your test class or test method with
method with <interfacename>@DirtiesContext</interfacename> (assuming <interfacename>@DirtiesContext</interfacename> (assuming
<classname>DirtiesContextTestExecutionListener</classname> has been <classname>DirtiesContextTestExecutionListener</classname> has been
configured, which is the default). This instructs Spring to reload configured, which is the default). This instructs Spring to reload the
the configuration and rebuild the application context before configuration and rebuild the application context before executing the
executing the next test.</para> next test.</para>
</section> </section>
<section id="testcontext-fixture-di"> <section id="testcontext-fixture-di">
<title>Dependency Injection of test fixtures</title> <title>Dependency Injection of test fixtures</title>
<para>When you use the <para>When you use the
<classname>DependencyInjectionTestExecutionListener</classname> &mdash; <classname>DependencyInjectionTestExecutionListener</classname>
which is configured by default &mdash; the dependencies of your which is configured by default — the dependencies of your test
test instances are <emphasis>injected</emphasis> from beans in the instances are <emphasis>injected</emphasis> from beans in the
application context that you configured with application context that you configured with
<interfacename>@ContextConfiguration</interfacename>. You may use setter <interfacename>@ContextConfiguration</interfacename>. You may use
injection, field injection, or both, depending on which annotations setter injection, field injection, or both, depending on which
you choose and whether you place them on setter methods or fields. For annotations you choose and whether you place them on setter methods or
consistency with the annotation support introduced in Spring 3.0, you fields. For consistency with the annotation support introduced in
can use Spring's <interfacename>@Autowired</interfacename> annotation Spring 3.0, you can use Spring's
or the <interfacename>@Inject</interfacename> annotation from JSR <interfacename>@Autowired</interfacename> annotation or the
300. </para> <interfacename>@Inject</interfacename> annotation from JSR 300.</para>
<tip> <tip>
<para>The TestContext framework does not instrument the manner in <para>The TestContext framework does not instrument the manner in
@ -1123,42 +1114,42 @@ public class ExtendedTest extends BaseTest {
effect for test classes.</para> effect for test classes.</para>
</tip> </tip>
<para>Because <interfacename>@Autowired</interfacename> used solely performs <link <para>Because <interfacename>@Autowired</interfacename> is used to
linkend="beans-factory-autowire"><emphasis>autowiring by perform <link linkend="beans-factory-autowire"><emphasis>autowiring by
type</emphasis></link>, if you have multiple bean definitions of the type</emphasis></link>, if you have multiple bean definitions of the
same type, you cannot rely on this approach for those particular same type, you cannot rely on this approach for those particular
beans. In that case, you can use <interfacename>@Autowired</interfacename> in beans. In that case, you can use
conjunction with <interfacename>@Qualifier</interfacename>. As of <interfacename>@Autowired</interfacename> in conjunction with
Spring 3.0 you may also choose to use <interfacename>@Qualifier</interfacename>. As of Spring 3.0 you may
<interfacename>@Inject</interfacename> in conjunction with also choose to use <interfacename>@Inject</interfacename> in
<interfacename>@Named</interfacename>. conjunction with <interfacename>@Named</interfacename>. Alternatively,
Alternatively, if your test class has access to its if your test class has access to its
<classname>ApplicationContext</classname>, you can perform an explicit <classname>ApplicationContext</classname>, you can perform an explicit
lookup by using (for example) a call to lookup by using (for example) a call to
<methodname>applicationContext.getBean("titleRepository")</methodname>. </para> <methodname>applicationContext.getBean("titleRepository")</methodname>.</para>
<para>If you do not want dependency injection applied to your test <para>If you do not want dependency injection applied to your test
instances, simply do not annotate fields or setter methods with instances, simply do not annotate fields or setter methods with
<interfacename>@Autowired</interfacename> or <interfacename>@Autowired</interfacename> or
<interfacename>@Inject</interfacename>. Alternatively, you can <interfacename>@Inject</interfacename>. Alternatively, you can disable
disable dependency injection altogether by explicitly configuring your dependency injection altogether by explicitly configuring your class
class with <interfacename>@TestExecutionListeners</interfacename> and with <interfacename>@TestExecutionListeners</interfacename> and
omitting omitting
<literal>DependencyInjectionTestExecutionListener.class</literal> from <literal>DependencyInjectionTestExecutionListener.class</literal> from
the list of listeners.</para> the list of listeners.</para>
<para>Consider the scenario of testing a <para>Consider the scenario of testing a
<classname>HibernateTitleRepository</classname> class, as outlined in the <link <classname>HibernateTitleRepository</classname> class, as outlined in
linkend="integration-testing-goals">Goals</link> section. The next two the <link linkend="integration-testing-goals">Goals</link> section.
code listings demonstrate the use of <interfacename>@Autowired</interfacename> on fields The next two code listings demonstrate the use of
and setter methods. The application context configuration is presented <interfacename>@Autowired</interfacename> on fields and setter
after all sample code listings.</para> methods. The application context configuration is presented after all
sample code listings.</para>
<note> <note>
<para>The dependency injection behavior in the following code <para>The dependency injection behavior in the following code
listings is not specific to JUnit. The same DI listings is not specific to JUnit. The same DI techniques can be
techniques can be used in conjunction with any testing used in conjunction with any testing framework.</para>
framework.</para>
<para>The following examples make calls to static assertion methods <para>The following examples make calls to static assertion methods
such as <literal>assertNotNull()</literal> but without prepending such as <literal>assertNotNull()</literal> but without prepending
@ -1168,9 +1159,9 @@ public class ExtendedTest extends BaseTest {
example.</para> example.</para>
</note> </note>
<para>The first code listing shows a JUnit-based implementation <para>The first code listing shows a JUnit-based implementation of the
of the test class that uses <interfacename>@Autowired</interfacename> test class that uses <interfacename>@Autowired</interfacename> for
for field injection.</para> field injection.</para>
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class) <programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
<lineannotation>// specifies the Spring configuration to load for this test fixture</lineannotation> <lineannotation>// specifies the Spring configuration to load for this test fixture</lineannotation>
@ -1190,8 +1181,8 @@ public class HibernateTitleRepositoryTests {
}</programlisting> }</programlisting>
<para>Alternatively, you can configure the class to use <para>Alternatively, you can configure the class to use
<interfacename>@Autowired</interfacename> for setter injection as <interfacename>@Autowired</interfacename> for setter injection as seen
seen below.</para> below.</para>
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class) <programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
<lineannotation>// specifies the Spring configuration to load for this test fixture</lineannotation> <lineannotation>// specifies the Spring configuration to load for this test fixture</lineannotation>
@ -1214,12 +1205,10 @@ public class HibernateTitleRepositoryTests {
} }
}</programlisting> }</programlisting>
<para>The preceding code listings use the same XML context file <para>The preceding code listings use the same XML context file
referenced by the <interfacename>@ContextConfiguration</interfacename> referenced by the <interfacename>@ContextConfiguration</interfacename>
annotation (that is, <literal>repository-config.xml</literal>), which looks like annotation (that is, <literal>repository-config.xml</literal>), which
this:</para> looks like this:</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt; <programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans" &lt;beans xmlns="http://www.springframework.org/schema/beans"
@ -1269,8 +1258,6 @@ public class HibernateTitleRepositoryTests {
name is used as a fallback qualifier value, so you may effectively name is used as a fallback qualifier value, so you may effectively
also point to a specific bean by name there (as shown above, also point to a specific bean by name there (as shown above,
assuming that "myDataSource" is the bean id).</para> assuming that "myDataSource" is the bean id).</para>
</note> </note>
</section> </section>
@ -1314,8 +1301,8 @@ public class HibernateTitleRepositoryTests {
transactional test method but outside the transactional context, for transactional test method but outside the transactional context, for
example, to verify the initial database state prior to execution of example, to verify the initial database state prior to execution of
your test or to verify expected transactional commit behavior after your test or to verify expected transactional commit behavior after
test execution (if the test was configured not to roll test execution (if the test was configured not to roll back the
back the transaction). transaction).
<classname>TransactionalTestExecutionListener</classname> supports the <classname>TransactionalTestExecutionListener</classname> supports the
<interfacename>@BeforeTransaction</interfacename> and <interfacename>@BeforeTransaction</interfacename> and
<interfacename>@AfterTransaction</interfacename> annotations exactly <interfacename>@AfterTransaction</interfacename> annotations exactly
@ -1328,11 +1315,11 @@ public class HibernateTitleRepositoryTests {
<tip> <tip>
<para>Any <emphasis>before methods</emphasis> (such as methods <para>Any <emphasis>before methods</emphasis> (such as methods
annotated with JUnit's <interfacename>@Before</interfacename>) annotated with JUnit's <interfacename>@Before</interfacename>) and
and any <emphasis>after methods</emphasis> (such as methods annotated any <emphasis>after methods</emphasis> (such as methods annotated
with JUnit's <interfacename>@After</interfacename>) with JUnit's <interfacename>@After</interfacename>) are executed
are executed <emphasis role="bold">within</emphasis> a transaction. <emphasis role="bold">within</emphasis> a transaction. In addition,
In addition, methods annotated with methods annotated with
<interfacename>@BeforeTransaction</interfacename> or <interfacename>@BeforeTransaction</interfacename> or
<interfacename>@AfterTransaction</interfacename> are naturally not <interfacename>@AfterTransaction</interfacename> are naturally not
executed for tests annotated with executed for tests annotated with
@ -1382,21 +1369,22 @@ public class FictitiousTransactionalTest {
}</programlisting> }</programlisting>
<anchor id="testcontext-tx-false-positives"/> <anchor id="testcontext-tx-false-positives" />
<note> <note>
<title>Avoid false positives when testing ORM code</title> <title>Avoid false positives when testing ORM code</title>
<para>When you test application code that manipulates the state of <para>When you test application code that manipulates the state of
the Hibernate session, make sure to <emphasis>flush</emphasis> the the Hibernate session, make sure to <emphasis>flush</emphasis> the
underlying session within test methods that execute that code. underlying session within test methods that execute that code.
Failing to flush the underlying session can Failing to flush the underlying session can produce <emphasis>false
produce <emphasis>false positives</emphasis>: your test may pass, positives</emphasis>: your test may pass, but the same code throws
but the same code throws an exception in a live, production an exception in a live, production environment. In the following
environment. In the following Hibernate-based example test case, one Hibernate-based example test case, one method demonstrates a false
method demonstrates a false positive, and the other method correctly positive, and the other method correctly exposes the results of
exposes the results of flushing the session. Note that this flushing the session. Note that this applies to JPA and any other
applies to JPA and any other ORM frameworks that maintain an ORM frameworks that maintain an in-memory <emphasis>unit of
in-memory <emphasis>unit of work</emphasis>.</para> work</emphasis>.</para>
<programlisting language="java"><lineannotation>// ...</lineannotation> <programlisting language="java"><lineannotation>// ...</lineannotation>
@ -1446,10 +1434,9 @@ public void updateWithSessionFlush() {
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para><literal>applicationContext</literal>: <para><literal>applicationContext</literal>: Use this
Use this variable to perform explicit bean variable to perform explicit bean lookups or to test the
lookups or to test the state of the context as a state of the context as a whole.</para>
whole.</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</listitem> </listitem>
@ -1477,15 +1464,16 @@ public void updateWithSessionFlush() {
</listitem> </listitem>
<listitem> <listitem>
<para><literal>simpleJdbcTemplate</literal>: Use this variable <para><literal>simpleJdbcTemplate</literal>: Use this
to execute SQL statements to query the database. variable to execute SQL statements to query the database.
Such queries can be used to confirm database state both Such queries can be used to confirm database state both
<emphasis>prior to</emphasis> and <emphasis>after</emphasis> <emphasis>prior to</emphasis> and <emphasis>after</emphasis>
execution of database-related application code, and Spring execution of database-related application code, and Spring
ensures that such queries run in the scope of the same ensures that such queries run in the scope of the same
transaction as the application code. When used in conjunction transaction as the application code. When used in
with an ORM tool, be sure to avoid conjunction with an ORM tool, be sure to avoid <link
<link linkend="testcontext-tx-false-positives">false positives</link>.</para> linkend="testcontext-tx-false-positives">false
positives</link>.</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</listitem> </listitem>
@ -1494,8 +1482,8 @@ public void updateWithSessionFlush() {
<tip> <tip>
<para>These classes are a convenience for extension. If you do not <para>These classes are a convenience for extension. If you do not
want your test classes to be tied to a Spring-specific class want your test classes to be tied to a Spring-specific class
hierarchy &mdash; for example, if you want to directly extend the class hierarchy for example, if you want to directly extend the class
you are testing &mdash; you can configure your own custom test classes you are testing you can configure your own custom test classes
by using by using
<interfacename>@RunWith(SpringJUnit4ClassRunner.class)</interfacename>, <interfacename>@RunWith(SpringJUnit4ClassRunner.class)</interfacename>,
<interfacename>@ContextConfiguration</interfacename>, <interfacename>@ContextConfiguration</interfacename>,
@ -1509,17 +1497,18 @@ public void updateWithSessionFlush() {
<para>The <emphasis>Spring TestContext Framework</emphasis> offers <para>The <emphasis>Spring TestContext Framework</emphasis> offers
full integration with JUnit 4.5+ through a custom runner (tested on full integration with JUnit 4.5+ through a custom runner (tested on
JUnit 4.5 &ndash; 4.8.1). By annotating test classes with JUnit 4.5 4.8.2). By annotating test classes with
<literal>@RunWith(SpringJUnit4ClassRunner.class)</literal>, <literal>@RunWith(SpringJUnit4ClassRunner.class)</literal>,
developers can implement standard JUnit-based unit and integration developers can implement standard JUnit-based unit and integration
tests and simultaneously reap the benefits of the TestContext tests and simultaneously reap the benefits of the TestContext
framework such as support for loading application contexts, framework such as support for loading application contexts,
dependency injection of test instances, transactional test method dependency injection of test instances, transactional test method
execution, and so on. The following code listing displays the minimal execution, and so on. The following code listing displays the
requirements for configuring a test class to run with the custom Spring minimal requirements for configuring a test class to run with the
Runner. <interfacename>@TestExecutionListeners</interfacename> is custom Spring Runner.
configured with an empty list in order to disable the default listeners, <interfacename>@TestExecutionListeners</interfacename> is configured
which otherwise would require an ApplicationContext to be configured with an empty list in order to disable the default listeners, which
otherwise would require an ApplicationContext to be configured
through <interfacename>@ContextConfiguration</interfacename>.</para> through <interfacename>@ContextConfiguration</interfacename>.</para>
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class) <programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
@ -1554,10 +1543,9 @@ public class SimpleTest {
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para><literal>applicationContext</literal>: <para><literal>applicationContext</literal>: Use this
Use this variable to perform explicit bean variable to perform explicit bean lookups or to test the
lookups or to test the state of the context as a state of the context as a whole.</para>
whole.</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</listitem> </listitem>
@ -1585,15 +1573,16 @@ public class SimpleTest {
</listitem> </listitem>
<listitem> <listitem>
<para><literal>simpleJdbcTemplate</literal>: Use this variable <para><literal>simpleJdbcTemplate</literal>: Use this
to execute SQL statements to query the database. variable to execute SQL statements to query the database.
Such queries can be used to confirm database state both Such queries can be used to confirm database state both
<emphasis>prior to</emphasis> and <emphasis>after</emphasis> <emphasis>prior to</emphasis> and <emphasis>after</emphasis>
execution of database-related application code, and Spring execution of database-related application code, and Spring
ensures that such queries run in the scope of the same ensures that such queries run in the scope of the same
transaction as the application code. When used in conjunction transaction as the application code. When used in
with an ORM tool, be sure to avoid conjunction with an ORM tool, be sure to avoid <link
<link linkend="testcontext-tx-false-positives">false positives</link>.</para> linkend="testcontext-tx-false-positives">false
positives</link>.</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</listitem> </listitem>
@ -1602,9 +1591,9 @@ public class SimpleTest {
<tip> <tip>
<para>These classes are a convenience for extension. If you do not <para>These classes are a convenience for extension. If you do not
want your test classes to be tied to a Spring-specific class want your test classes to be tied to a Spring-specific class
hierarchy &mdash; for example, if you want to directly extend the class hierarchy for example, if you want to directly extend the class
you are testing &mdash; you can configure your own custom test classes by you are testing — you can configure your own custom test classes
using <interfacename>@ContextConfiguration</interfacename>, by using <interfacename>@ContextConfiguration</interfacename>,
<interfacename>@TestExecutionListeners</interfacename>, and so on, <interfacename>@TestExecutionListeners</interfacename>, and so on,
and by manually instrumenting your test class with a and by manually instrumenting your test class with a
<classname>TestContextManager</classname>. See the source code of <classname>TestContextManager</classname>. See the source code of
@ -1618,10 +1607,10 @@ public class SimpleTest {
<section id="testing-examples-petclinic"> <section id="testing-examples-petclinic">
<title>PetClinic example</title> <title>PetClinic example</title>
<para>The PetClinic application, available from the <para>The PetClinic application, available from the <link
<link linkend="new-in-3.0-samples">samples repository</link>, linkend="new-in-3.0-samples">samples repository</link>, illustrates
illustrates several features of the <emphasis>Spring several features of the <emphasis>Spring TestContext
TestContext Framework</emphasis> in a JUnit 4.5+ environment. Most test Framework</emphasis> in a JUnit 4.5+ environment. Most test
functionality is included in the functionality is included in the
<classname>AbstractClinicTests</classname>, for which a partial listing <classname>AbstractClinicTests</classname>, for which a partial listing
is shown below:</para> is shown below:</para>
@ -1664,8 +1653,8 @@ public abstract class AbstractClinicTests <emphasis role="bold">extends Abstract
</listitem> </listitem>
<listitem> <listitem>
<para>The <literal>clinic</literal> instance variable &mdash; the <para>The <literal>clinic</literal> instance variable the
application object being tested &mdash; is set by Dependency Injection application object being tested is set by Dependency Injection
through <interfacename>@Autowired</interfacename> semantics.</para> through <interfacename>@Autowired</interfacename> semantics.</para>
</listitem> </listitem>
@ -1684,8 +1673,8 @@ public abstract class AbstractClinicTests <emphasis role="bold">extends Abstract
tests in <classname>AbstractClinicTests</classname> depend on a tests in <classname>AbstractClinicTests</classname> depend on a
minimum amount of data already in the database before the test cases minimum amount of data already in the database before the test cases
run. Alternatively, you might choose to populate the database within run. Alternatively, you might choose to populate the database within
the test fixture set up of your test cases &mdash; again, the test fixture set up of your test cases — again, within the same
within the same transaction as the tests.</para> transaction as the tests.</para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
@ -1710,8 +1699,8 @@ public abstract class AbstractClinicTests <emphasis role="bold">extends Abstract
<interfacename>@ContextConfiguration</interfacename> is declared without <interfacename>@ContextConfiguration</interfacename> is declared without
any specific resource locations, the <emphasis>Spring TestContext any specific resource locations, the <emphasis>Spring TestContext
Framework</emphasis> loads an application context from all the beans Framework</emphasis> loads an application context from all the beans
defined in <literal>AbstractClinicTests-context.xml</literal> (i.e., defined in <literal>AbstractClinicTests-context.xml</literal> (i.e., the
the inherited locations) and inherited locations) and
<literal>HibernateClinicTests-context.xml</literal>, with <literal>HibernateClinicTests-context.xml</literal>, with
<literal>HibernateClinicTests-context.xml</literal> possibly overriding <literal>HibernateClinicTests-context.xml</literal> possibly overriding
beans defined in beans defined in
@ -1721,11 +1710,11 @@ public abstract class AbstractClinicTests <emphasis role="bold">extends Abstract
public class HibernateClinicTests extends AbstractClinicTests { } public class HibernateClinicTests extends AbstractClinicTests { }
</programlisting> </programlisting>
<para>In a large-scale application, the Spring configuration is <para>In a large-scale application, the Spring configuration is often
often split across multiple files. Consequently, configuration locations split across multiple files. Consequently, configuration locations are
are typically specified in a common base class for all application-specific typically specified in a common base class for all application-specific
integration tests. Such a base class may also add useful instance integration tests. Such a base class may also add useful instance
variables &mdash; populated by Dependency Injection, naturally &mdash; such as a variables — populated by Dependency Injection, naturally — such as a
<classname>SessionFactory</classname> in the case of an application <classname>SessionFactory</classname> in the case of an application
using Hibernate.</para> using Hibernate.</para>
@ -1761,15 +1750,15 @@ public class HibernateClinicTests extends AbstractClinicTests { }
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para><ulink url="http://www.junit.org/">JUnit</ulink>: <para><ulink url="http://www.junit.org/">JUnit</ulink>:
<quote><emphasis>A programmer-oriented testing framework for Java</emphasis></quote>. <quote><emphasis>A programmer-oriented testing framework for
Used by the Spring Framework in its test suite.</para> Java</emphasis></quote>. Used by the Spring Framework in its test
suite.</para>
</listitem> </listitem>
<listitem> <listitem>
<para><ulink url="http://testng.org/">TestNG</ulink>: A testing <para><ulink url="http://testng.org/">TestNG</ulink>: A testing
framework inspired by JUnit with added support for Java 5 framework inspired by JUnit with added support for Java 5 annotations,
annotations, test groups, data-driven testing, distributed testing, test groups, data-driven testing, distributed testing, etc.</para>
etc.</para>
</listitem> </listitem>
<listitem> <listitem>
@ -1785,11 +1774,11 @@ public class HibernateClinicTests extends AbstractClinicTests { }
</listitem> </listitem>
<listitem> <listitem>
<para><ulink url="http://www.easymock.org/">EasyMock</ulink>: <para><ulink url="http://www.easymock.org/">EasyMock</ulink>: Java
Java library <quote><emphasis>that provides Mock Objects for interfaces library <quote><emphasis>that provides Mock Objects for interfaces
(and objects through the class extension) by generating them (and objects through the class extension) by generating them on the
on the fly using Java's proxy mechanism.</emphasis></quote> fly using Java's proxy mechanism.</emphasis></quote> Used by the
Used by the Spring Framework in its test suite.</para> Spring Framework in its test suite.</para>
</listitem> </listitem>
<listitem> <listitem>