From 2b24e99d44cce6c655f572986fd9ac50cbfeb09b Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 10 Mar 2013 14:49:10 +0100 Subject: [PATCH] Reformat the testing chapter This commit reformats the testing chapter (and adds minor polishing changes) in order to avoid massive merge diffs in upcoming commits. Issue: SPR-10357 --- src/reference/docbook/testing.xml | 1580 ++++++++++++++--------------- 1 file changed, 757 insertions(+), 823 deletions(-) diff --git a/src/reference/docbook/testing.xml b/src/reference/docbook/testing.xml index 7e819cec47..e5bb9aafd7 100644 --- a/src/reference/docbook/testing.xml +++ b/src/reference/docbook/testing.xml @@ -1,12 +1,13 @@ - + Testing
@@ -14,11 +15,10 @@ Testing is an integral part of enterprise software development. This chapter focuses on the value-add of the IoC principle to unit testing and on the benefits of the - Spring Framework's support for integration testing. (A - thorough treatment of testing in the enterprise is beyond the scope of - this reference manual.) + linkend="unit-testing">unit testing and on the benefits of the Spring + Framework's support for integration + testing. (A thorough treatment of testing in the enterprise + is beyond the scope of this reference manual.)
@@ -27,21 +27,21 @@ Dependency Injection should make your code less dependent on the container than it would be with traditional Java EE development. The POJOs that make up your application should be testable in JUnit or TestNG tests, - with objects simply instantiated using the new - operator, without Spring or any other container. You - can use mock objects (in conjunction - with other valuable testing techniques) to test your code in isolation. If - you follow the architecture recommendations for Spring, the resulting - clean layering and componentization of your codebase will facilitate - easier unit testing. For example, you can test service layer objects by - stubbing or mocking DAO or Repository interfaces, without needing to - access persistent data while running unit tests. + with objects simply instantiated using the new operator, + without Spring or any other container. You can use + mock objects (in conjunction with other + valuable testing techniques) to test your code in isolation. If you follow + the architecture recommendations for Spring, the resulting clean layering + and componentization of your codebase will facilitate easier unit testing. + For example, you can test service layer objects by stubbing or mocking DAO + or Repository interfaces, without needing to access persistent data while + running unit tests. True unit tests typically run extremely quickly, as there is no runtime infrastructure to set up. Emphasizing true unit tests as part of - your development methodology will boost your productivity. You may not - need this section of the testing chapter to help you write effective unit - tests for your IoC-based applications. For certain unit testing scenarios, + your development methodology will boost your productivity. You may not need + this section of the testing chapter to help you write effective unit tests + for your IoC-based applications. For certain unit testing scenarios, however, the Spring Framework provides the following mock objects and testing support classes. @@ -54,10 +54,9 @@ The org.springframework.mock.env package contains mock implementations of the Environment and - PropertySource abstractions introduced - in Spring 3.1 (see and ). + PropertySource abstractions introduced in + Spring 3.1 (see and + ). MockEnvironment and MockPropertySource are useful for developing out-of-container tests for code that depends on @@ -68,12 +67,12 @@ JNDI The org.springframework.mock.jndi package - contains an implementation of the JNDI SPI, which you can use to set - up a simple JNDI environment for test suites or stand-alone - applications. If, for example, JDBC DataSources - get bound to the same JNDI names in test code as within a Java EE - container, you can reuse both application code and configuration in - testing scenarios without modification. + contains an implementation of the JNDI SPI, which you can use to set up + a simple JNDI environment for test suites or stand-alone applications. + If, for example, JDBC DataSources get bound to + the same JNDI names in test code as within a Java EE container, you can + reuse both application code and configuration in testing scenarios + without modification.
@@ -81,8 +80,8 @@ The org.springframework.mock.web package contains a comprehensive set of Servlet API mock objects, targeted at - usage with Spring's Web MVC framework, which are useful for testing - web contexts and controllers. These mock objects are generally more + usage with Spring's Web MVC framework, which are useful for testing web + contexts and controllers. These mock objects are generally more convenient to use than dynamic mock objects such as EasyMock or existing Servlet API mock objects such as The org.springframework.test.util package contains ReflectionTestUtils, which is a collection of reflection-based utility methods. Developers use these - methods in unit and integration testing scenarios in which they need - to set a non-public field or invoke a + methods in unit and integration testing scenarios in which they need to + set a non-public field or invoke a non-public setter method when testing application code involving, for example: @@ -124,8 +123,8 @@ Spring's support for annotations such as @Autowired, @Inject, and - @Resource, which provides - dependency injection for private or + @Resource, which provides dependency + injection for private or protected fields, setter methods, and configuration methods. @@ -136,9 +135,9 @@ Spring MVC The org.springframework.test.web package - contains ModelAndViewAssert, which you can use - in combination with JUnit, TestNG, or any other testing framework for - unit tests dealing with Spring MVC ModelAndView + contains ModelAndViewAssert, which you can use in + combination with JUnit, TestNG, or any other testing framework for unit + tests dealing with Spring MVC ModelAndView objects. @@ -149,8 +148,7 @@ MockHttpServletRequest, MockHttpSession, and so on from the - org.springframework.mock.web - package. + org.springframework.mock.web package.
@@ -164,13 +162,12 @@ It is important to be able to perform some integration testing without requiring deployment to your application server or connecting to - other enterprise infrastructure. This will enable you to test things - such as: + other enterprise infrastructure. This will enable you to test things such + as: - The correct wiring of your Spring IoC container - contexts. + The correct wiring of your Spring IoC container contexts. @@ -182,30 +179,29 @@ 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 - version and might also be in the long - org.springframework.test form, depending on where - you get it from (see 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 - container. This testing does not rely on an application server or other - deployment environment. Such tests are slower to run than unit tests but - much faster than the equivalent Cactus tests or remote tests that rely - on deployment to an application server. + module. 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 + get it from (see 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 container. This + testing does not rely on an application server or other deployment + environment. Such tests are slower to run than unit tests but much faster + than the equivalent Cactus tests or remote tests that rely on deployment + to an application server. In Spring 2.5 and later, unit and integration testing support is provided in the form of the annotation-driven Spring TestContext Framework. The - TestContext framework is agnostic of the actual testing framework in - use, thus allowing instrumentation of tests in various environments - including JUnit, TestNG, and so on. + TestContext framework is agnostic of the actual testing framework in use, + thus allowing instrumentation of tests in various environments including + JUnit, TestNG, and so on. JUnit 3.8 support is deprecated - As of Spring 3.0, the legacy JUnit 3.8 base class hierarchy - (i.e., + As of Spring 3.0, the legacy JUnit 3.8 base class hierarchy (i.e., AbstractDependencyInjectionSpringContextTests, AbstractTransactionalDataSourceSpringContextTests, etc.) is officially deprecated and will be removed in a later release. @@ -221,10 +217,10 @@ officially deprecated and will be removed in a later release. Any test classes based on this code should be migrated to the JUnit 4 or TestNG support provided by the Spring - TestContext Framework. Similarly, any test methods annotated - with @ExpectedException should be - modified to use the built-in support for expected exceptions in JUnit - and TestNG. + TestContext Framework. Similarly, any test methods annotated with + @ExpectedException should be modified to + use the built-in support for expected exceptions in JUnit and + TestNG. @@ -252,9 +248,8 @@ To supply Spring-specific base - classes that assist developers in writing integration - tests. + linkend="testing-support-classes">Spring-specific base classes + that assist developers in writing integration tests. @@ -267,18 +262,18 @@ The Spring TestContext Framework provides consistent loading of Spring ApplicationContexts and WebApplicationContexts as well as caching of - those contexts. Support for the caching of loaded contexts is - important, because startup time can become an issue — not because of - the overhead of Spring itself, but because the objects instantiated by - the Spring 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 mapping files, and incurring that cost before running every - test in every test fixture leads to slower overall test runs that - reduce developer productivity. + those contexts. Support for the caching of loaded contexts is important, + because startup time can become an issue — not because of the overhead + of Spring itself, but because the objects instantiated by the Spring + 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 + mapping files, and incurring that cost before running every test in + every test fixture leads to slower overall test runs that reduce + developer productivity. Test classes typically declare either an array of - resource locations for XML configuration metadata - — often in the classpath — or an array of annotated + resource locations for XML configuration metadata — + often in the classpath — or an array of annotated classes that is used to configure the application. These locations or classes are the same as or similar to those specified in web.xml or other deployment configuration @@ -291,11 +286,10 @@ test suite means all tests run in the same JVM — for example, all tests run from an Ant, Maven, or Gradle build for a given project or module. 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 — the - TestContext framework can be configured to reload the configuration - and rebuild the application context before executing the next - test. + application context and requires reloading — for example, by modifying a + bean definition or the state of an application object — the TestContext + framework can be configured to reload the configuration and rebuild the + application context before executing the next test. See context management and caching with the TestContext @@ -305,15 +299,15 @@
Dependency Injection of test fixtures - When the TestContext framework loads your application context, - it can optionally configure instances of your test classes via - Dependency Injection. This provides a convenient mechanism for setting - up test fixtures using preconfigured beans from your application - context. A strong benefit here is that you can reuse application - contexts across various testing scenarios (e.g., for configuring - Spring-managed object graphs, transactional proxies, - DataSources, etc.), thus avoiding the need to - duplicate complex test fixture setup for individual test cases. + When the TestContext framework loads your application context, it + can optionally configure instances of your test classes via Dependency + Injection. This provides a convenient mechanism for setting up test + fixtures using preconfigured beans from your application context. A + strong benefit here is that you can reuse application contexts across + various testing scenarios (e.g., for configuring Spring-managed object + graphs, transactional proxies, DataSources, + etc.), thus avoiding the need to duplicate complex test fixture setup + for individual test cases. As an example, consider the scenario where we have a class, HibernateTitleRepository, that implements data @@ -322,22 +316,22 @@ - The Spring configuration: basically, is everything related - to the configuration of the + The Spring configuration: basically, is everything related to + the configuration of the HibernateTitleRepository bean correct and present? - The Hibernate mapping file configuration: is everything - mapped correctly, and are the correct lazy-loading settings in + The Hibernate mapping file configuration: is everything mapped + correctly, and are the correct lazy-loading settings in place? The logic of the - HibernateTitleRepository: does the - configured instance of this class perform as anticipated? + HibernateTitleRepository: does the configured + instance of this class perform as anticipated? @@ -351,21 +345,20 @@ One common issue in tests that access a real database is their effect on the state of the persistence store. Even when you're using a development database, changes to the state may affect future tests. - Also, many operations — such as inserting or modifying persistent data - — cannot be performed (or verified) outside a transaction. + Also, many operations — such as inserting or modifying persistent data — + cannot be performed (or verified) outside a transaction. The TestContext framework addresses this issue. By default, the framework will create and roll back a transaction for each test. You - simply write code that can assume the existence of a transaction. If - you call transactionally proxied objects in your tests, they will - behave correctly, according to their configured transactional - semantics. In addition, if a test method deletes the contents of - selected tables while running within the transaction managed for the - test, the transaction will roll back by default, and the database will - return to its state prior to execution of the test. Transactional - support is provided to a test via a - PlatformTransactionManager bean defined in the - test's application context. + simply write code that can assume the existence of a transaction. If you + call transactionally proxied objects in your tests, they will behave + correctly, according to their configured transactional semantics. In + addition, if a test method deletes the contents of selected tables while + running within the transaction managed for the test, the transaction + will roll back by default, and the database will return to its state + prior to execution of the test. Transactional support is provided to a + test via a PlatformTransactionManager bean + defined in the test's application context. If you want a transaction to commit — unusual, but occasionally useful when you want a particular test to populate or modify the @@ -384,10 +377,10 @@ Support classes for integration testing The Spring TestContext Framework provides several - abstract support classes that simplify the writing - of integration tests. These base test classes provide well-defined - hooks into the testing framework as well as convenient instance - variables and methods, which enable you to access: + abstract support classes that simplify the writing of + integration tests. These base test classes provide well-defined hooks + into the testing framework as well as convenient instance variables and + methods, which enable you to access: @@ -400,18 +393,18 @@ A JdbcTemplate, for executing SQL statements to query the database. Such queries can be used to confirm database state both prior to and - after execution of database-related - application code, and Spring ensures that such queries run in the - scope of the same transaction as the application code. When used - in conjunction with an ORM tool, be sure to avoid after execution of database-related application + code, and Spring ensures that such queries run in the scope of the + same transaction as the application code. When used in conjunction + with an ORM tool, be sure to avoid false positives. In addition, you may want to create your own custom, - application-wide superclass with instance variables and methods - specific to your project. + application-wide superclass with instance variables and methods specific + to your project. See support classes for the TestContext @@ -435,8 +428,8 @@ The spring-jdbc module provides support for configuring and launching an embedded database which can be used in integration tests that interact with a database. For details, see and . + linkend="jdbc-embedded-database-support"/> and .
@@ -449,8 +442,7 @@ Spring-specific annotations that you can use in your unit and integration tests in conjunction with the TestContext framework. Refer to the respective Javadoc for further information, - including default attribute values, attribute aliases, and so - on. + including default attribute values, attribute aliases, and so on. @@ -458,8 +450,8 @@ @ContextConfiguration - Defines class-level metadata that is used to determine how - to load and configure an + Defines class-level metadata that is used to determine how to + load and configure an ApplicationContext for integration tests. Specifically, @ContextConfiguration declares @@ -480,36 +472,34 @@ public class XmlApplicationContextTests { } @ContextConfiguration(classes=TestConfig.class) + role="bold">classes = TestConfig.class) public class ConfigClassApplicationContextTests { // class body... } As an alternative or in addition to declaring resource locations or annotated classes, - @ContextConfiguration may be used - to declare - ApplicationContextInitializer + @ContextConfiguration may be used to + declare ApplicationContextInitializer classes. @ContextConfiguration(initializers=CustomContextIntializer.class) + role="bold">initializers = CustomContextIntializer.class) public class ContextInitializerTests { // class body... } @ContextConfiguration may optionally be used to declare the - ContextLoader strategy as well. - Note, however, that you typically do not need to explicitly - configure the loader since the default loader supports either - resource locations or annotated - classes as well as - initializers. + ContextLoader strategy as well. Note, + however, that you typically do not need to explicitly configure the + loader since the default loader supports either resource + locations or annotated classes + as well as initializers. @ContextConfiguration(locations="/test-context.xml", loader=CustomContextLoader.class) + role="bold">locations = "/test-context.xml", loader = CustomContextLoader.class) public class CustomLoaderXmlApplicationContextTests { // class body... } @@ -517,8 +507,8 @@ public class CustomLoaderXmlApplicationContextTests { @ContextConfiguration provides support for inheriting resource - locations or configuration classes as well as context - initializers declared by superclasses by default. + locations or configuration classes as well as context initializers + declared by superclasses by default. See Context @@ -535,16 +525,15 @@ public class CustomLoaderXmlApplicationContextTests { ApplicationContext loaded for an integration test should be a WebApplicationContext. The mere - presence of @WebAppConfiguration on - a test class ensures that a - WebApplicationContext will be - loaded for the test, using the default value of + presence of @WebAppConfiguration on a + test class ensures that a + WebApplicationContext will be loaded + for the test, using the default value of "file:src/main/webapp" for the path to the root of the web application (i.e., the resource base path). The resource base path is used behind the scenes to create a MockServletContext which serves - as the ServletContext for the - test's + as the ServletContext for the test's WebApplicationContext. @ContextConfiguration @@ -556,9 +545,9 @@ public class WebAppTests { To override the default, specify a different base resource path via the implicit value attribute. Both - classpath: and file: - resource prefixes are supported. If no resource prefix is supplied - the path is assumed to be a file system resource. + classpath: and file: resource + prefixes are supported. If no resource prefix is supplied the path + is assumed to be a file system resource. @ContextConfiguration @WebAppConfiguration("classpath:test-web-resources") @@ -566,14 +555,12 @@ public class WebAppTests { // class body... } - Note that - @WebAppConfiguration must be used - in conjunction with - @ContextConfiguration, either - within a single test class or within a test class hierarchy. See - the Javadoc for - @WebAppConfiguration for further - details. + Note that @WebAppConfiguration + must be used in conjunction with + @ContextConfiguration, either within + a single test class or within a test class hierarchy. See the + Javadoc for @WebAppConfiguration for + further details. @@ -581,9 +568,9 @@ public class WebAppTests { @ActiveProfiles A class-level annotation that is used to declare which - bean definition profiles should be active - when loading an ApplicationContext - for test classes. + bean definition profiles should be active when + loading an ApplicationContext for + test classes. @ContextConfiguration @ActiveProfiles("dev") @@ -599,8 +586,8 @@ public class DeveloperIntegrationTests { @ActiveProfiles provides - support for inheriting active bean - definition profiles declared by superclasses by default. + support for inheriting active bean definition + profiles declared by superclasses by default. See After the current test class, when declared on a class - with class mode set to AFTER_CLASS, which - is the default class mode. + with class mode set to AFTER_CLASS, which is + the default class mode. @@ -636,8 +623,7 @@ public class DeveloperIntegrationTests { - After the current test, when declared on a - method. + After the current test, when declared on a method. @@ -646,14 +632,14 @@ public class DeveloperIntegrationTests { supplied a new context. With JUnit 4.5+ or TestNG you can use - @DirtiesContext as both a - class-level and method-level annotation within the same test - class. In such scenarios, the - ApplicationContext is marked as - dirty after any such annotated method as well - as after the entire class. If the ClassMode - is set to AFTER_EACH_TEST_METHOD, the context - is marked dirty after each test method in the class. + @DirtiesContext as both a class-level + and method-level annotation within the same test class. In such + scenarios, the ApplicationContext is + marked as dirty after any such annotated method + as well as after the entire class. If the + ClassMode is set to + AFTER_EACH_TEST_METHOD, the context is marked + dirty after each test method in the class. @DirtiesContext public class ContextDirtyingTests { @@ -675,8 +661,8 @@ public void testProcessWhichDirtiesAppCtx() { When an application context is marked dirty, it is removed from the testing framework's cache and closed; thus the underlying Spring container - is rebuilt for any subsequent test that requires a context with - the same set of resource locations. + is rebuilt for any subsequent test that requires a context with the + same configuration metadata. @@ -687,8 +673,8 @@ public void testProcessWhichDirtiesAppCtx() { Defines class-level metadata for configuring which TestExecutionListeners should be registered with the TestContextManager. - Typically, @TestExecutionListeners - is used in conjunction with + Typically, @TestExecutionListeners is + used in conjunction with @ContextConfiguration. @ContextConfiguration @@ -710,23 +696,21 @@ public class CustomTestExecutionListenerTests { Defines class-level metadata for configuring transactional tests. Specifically, the bean name of the PlatformTransactionManager that - should be used to drive transactions can be explicitly specified - if there are multiple beans of type + should be used to drive transactions can be explicitly specified if + there are multiple beans of type PlatformTransactionManager in the - test's ApplicationContext and if - the bean name of the desired + test's ApplicationContext and if the + bean name of the desired PlatformTransactionManager is not "transactionManager". In addition, you can change the - defaultRollback flag to - false. Typically, - @TransactionConfiguration is used - in conjunction with + defaultRollback flag to false. + Typically, @TransactionConfiguration + is used in conjunction with @ContextConfiguration. @ContextConfiguration -@TransactionConfiguration(transactionManager="txMgr", defaultRollback=false) +@TransactionConfiguration(transactionManager = "txMgr", defaultRollback = false) public class CustomConfiguredTransactionalTests { // class body... } @@ -752,8 +736,8 @@ public class CustomConfiguredTransactionalTests { Indicates whether the transaction for the annotated test method should be rolled back after the test - method has completed. If true, the transaction - is rolled back; otherwise, the transaction is committed. Use + method has completed. If true, the transaction is + rolled back; otherwise, the transaction is committed. Use @Rollback to override the default rollback flag configured at the class level. @@ -766,13 +750,12 @@ public void testProcessWithoutRollback() { - @BeforeTransaction - + @BeforeTransaction Indicates that the annotated public void - method should be executed before a - transaction is started for test methods configured to run within a - transaction via the @Transactional + method should be executed before a transaction + is started for test methods configured to run within a transaction + via the @Transactional annotation. @BeforeTransaction @@ -783,8 +766,7 @@ public void testProcessWithoutRollback() { - @AfterTransaction - + @AfterTransaction Indicates that the annotated public void method should be executed after a transaction @@ -800,12 +782,11 @@ public void testProcessWithoutRollback() { - @NotTransactional - + @NotTransactional The presence of this annotation indicates that the annotated - test method must not execute in a - transactional context. + test method must not execute in a transactional + context. @NotTransactional @Test @@ -817,14 +798,14 @@ public void testProcessWithoutTransaction() { @NotTransactional is deprecated As of Spring 3.0, - @NotTransactional is deprecated - in favor of moving the non-transactional - test method to a separate (non-transactional) test class or to a + @NotTransactional is deprecated in + favor of moving the non-transactional test + method to a separate (non-transactional) test class or to a @BeforeTransaction or @AfterTransaction method. As an alternative to annotating an entire class with - @Transactional, consider - annotating individual methods with + @Transactional, consider annotating + individual methods with @Transactional; doing so allows a mix of transactional and non-transactional methods in the same test class without the need for using @@ -839,8 +820,8 @@ public void testProcessWithoutTransaction() { The following annotations are supported with standard semantics for all configurations of the Spring TestContext Framework. Note that - these annotations are not specific to tests and can be used anywhere - in the Spring Framework. + these annotations are not specific to tests and can be used anywhere in + the Spring Framework. @@ -856,14 +837,13 @@ public void testProcessWithoutTransaction() { @Resource - (javax.annotation) if JSR-250 is - present + (javax.annotation) if JSR-250 is present - - @Inject (javax.inject) - if JSR-330 is present + @Inject + (javax.inject) if JSR-330 is + present @@ -910,13 +890,13 @@ public void testProcessWithoutTransaction() { @PostConstruct, that method will be executed before any before methods of the underlying test framework (e.g., methods annotated with JUnit's - @Before), and that will apply for - every test method in the test class. On the other hand, if a method - within a test class is annotated with - @PreDestroy, that method will - never be executed. Within a test - class it is therefore recommended to use test lifecycle callbacks - from the underlying test framework instead of + @Before), and that will apply for every + test method in the test class. On the other hand, if a method within a + test class is annotated with + @PreDestroy, that method will never be executed. Within a test class it is + therefore recommended to use test lifecycle callbacks from the + underlying test framework instead of @PostConstruct and @PreDestroy. @@ -925,8 +905,8 @@ public void testProcessWithoutTransaction() {
Spring JUnit Testing Annotations - The following annotations are only - supported when used in conjunction with the The following annotations are only supported + when used in conjunction with the SpringJUnit4ClassRunner or the JUnit support classes. @@ -945,8 +925,7 @@ public void testProcessWithoutTransaction() { method-level usage. @IfProfileValue(name="java.vendor", value="Sun Microsystems Inc.") + role="bold">name="java.vendor", value="Sun Microsystems Inc.") @Test public void testProcessWhichRunsOnlyOnSunJvm() { // some logic that should run only on Java VMs from Sun Microsystems @@ -955,13 +934,11 @@ public void testProcessWhichRunsOnlyOnSunJvm() { Alternatively, you can configure @IfProfileValue with a list of values (with OR semantics) - to achieve TestNG-like support for test - groups in a JUnit environment. Consider the following - example: + to achieve TestNG-like support for test groups + in a JUnit environment. Consider the following example: @IfProfileValue(name="test-groups", values={"unit-tests", "integration-tests"}) + role="bold">name="test-groups", values={"unit-tests", "integration-tests"}) @Test public void testProcessWhichRunsForUnitOrIntegrationTestGroups() { // some logic that should run only for unit and integration test groups @@ -992,24 +969,23 @@ public class CustomProfileValueSourceTests { @Timed - Indicates that the annotated test method must finish - execution in a specified time period (in milliseconds). If the - text execution time exceeds the specified time period, the test - fails. + Indicates that the annotated test method must finish execution + in a specified time period (in milliseconds). If the text execution + time exceeds the specified time period, the test fails. - The time period includes execution of the test method - itself, any repetitions of the test (see + The time period includes execution of the test method itself, + any repetitions of the test (see @Repeat), as well as any - set up or tear down of - the test fixture. + set up or tear down of the + test fixture. @Timed(millis=1000) public void testProcessWithOneSecondTimeout() { // some logic that should not take longer than 1 second to execute } - Spring's @Timed annotation - has different semantics than JUnit's + Spring's @Timed annotation has + different semantics than JUnit's @Test(timeout=...) support. Specifically, due to the manner in which JUnit handles test execution timeouts (that is, by executing the test method in a @@ -1017,23 +993,23 @@ public void testProcessWithOneSecondTimeout() { @Test(timeout=...) applies to each iteration in the case of repetitions and preemptively fails the test if the test takes too long. Spring's - @Timed, on the other hand, times - the total test execution time (including all + @Timed, on the other hand, times the + total test execution time (including all repetitions) and does not preemptively fail the test but rather waits for the test to complete before failing. - - @Repeat + @Repeat + Indicates that the annotated test method must be executed repeatedly. The number of times that the test method is to be executed is specified in the annotation. The scope of execution to be repeated includes execution of - the test method itself as well as any set up - or tear down of the test fixture. + the test method itself as well as any set up or + tear down of the test fixture. @Repeat(10) @Test @@ -1060,20 +1036,18 @@ public void testProcessRepeatedly() { In addition to generic testing infrastructure, the TestContext framework provides explicit support for JUnit and TestNG in the form of abstract support classes. For JUnit, Spring also - provides a custom JUnit Runner that - allows one to write so-called POJO test classes. - POJO test classes are not required to extend a particular class - hierarchy. + provides a custom JUnit Runner that allows + one to write so-called POJO test classes. POJO test + classes are not required to extend a particular class hierarchy. The following section provides an overview of the internals of the TestContext framework. If you are only interested in using the framework and not necessarily interested in extending it with your own custom - listeners or custom loaders, feel free to go directly to the - configuration (context - management, dependency - injection, transaction - management), support - classes, and context management, + dependency injection, transaction management), support classes, and annotation support sections. @@ -1086,21 +1060,20 @@ public void testProcessRepeatedly() { TestExecutionListener, ContextLoader, and SmartContextLoader interfaces. A - TestContextManager is created on a per-test - basis (e.g., for the execution of a single test method in JUnit). The + TestContextManager is created on a per-test basis + (e.g., for the execution of a single test method in JUnit). The TestContextManager in turn manages a - TestContext that holds the context of the - current test. The TestContextManager also - updates the state of the TestContext as the - test progresses and delegates to - TestExecutionListeners, which - instrument the actual test execution by providing dependency + TestContext that holds the context of the current + test. The TestContextManager also updates the + state of the TestContext as the test progresses + and delegates to TestExecutionListeners, + which instrument the actual test execution by providing dependency injection, managing transactions, and so on. A ContextLoader (or SmartContextLoader) is responsible for - loading an ApplicationContext for a - given test class. Consult the Javadoc and the Spring test suite for - further information and examples of various implementations. + loading an ApplicationContext for a given + test class. Consult the Javadoc and the Spring test suite for further + information and examples of various implementations. @@ -1125,8 +1098,8 @@ public void testProcessRepeatedly() { - prior to any before class methods - of a particular testing framework + prior to any before class methods of + a particular testing framework @@ -1151,15 +1124,14 @@ public void testProcessRepeatedly() { - TestExecutionListener: - Defines a listener API for reacting to test - execution events published by the - TestContextManager with which the listener - is registered. + TestExecutionListener: Defines + a listener API for reacting to test execution + events published by the TestContextManager + with which the listener is registered. Spring provides four - TestExecutionListener - implementations that are configured by default: + TestExecutionListener implementations + that are configured by default: ServletTestExecutionListener, DependencyInjectionTestExecutionListener, DirtiesContextTestExecutionListener, and @@ -1168,16 +1140,14 @@ public void testProcessRepeatedly() { WebApplicationContext, dependency injection of the test instance, handling of the @DirtiesContext annotation, and - transactional test execution with default rollback - semantics. + transactional test execution with default rollback semantics. ContextLoader: Strategy interface introduced in Spring 2.5 for loading an - ApplicationContext for an - integration test managed by the Spring TestContext - Framework. + ApplicationContext for an integration + test managed by the Spring TestContext Framework. As of Spring 3.1, implement SmartContextLoader instead of this @@ -1191,8 +1161,8 @@ public void testProcessRepeatedly() { introduced in Spring 3.1. The SmartContextLoader SPI - supersedes the ContextLoader SPI - that was introduced in Spring 2.5. Specifically, a + supersedes the ContextLoader SPI that + was introduced in Spring 2.5. Specifically, a SmartContextLoader can choose to process resource locations, annotated classes, or context @@ -1207,9 +1177,9 @@ public void testProcessRepeatedly() { DelegatingSmartContextLoader: one of two default loaders which delegates internally to an AnnotationConfigContextLoader or a - GenericXmlContextLoader depending - either on the configuration declared for the test class or on - the presence of default locations or default configuration + GenericXmlContextLoader depending either + on the configuration declared for the test class or on the + presence of default locations or default configuration classes. @@ -1220,8 +1190,8 @@ public void testProcessRepeatedly() { GenericXmlWebContextLoader depending either on the configuration declared for the test class or on the presence of default locations or default configuration - classes. A web ContextLoader - will only be used if + classes. A web ContextLoader will + only be used if @WebAppConfiguration is present on the test class. @@ -1241,14 +1211,14 @@ public void testProcessRepeatedly() { GenericXmlContextLoader: loads a - standard ApplicationContext - from XML resource locations. + standard ApplicationContext from + XML resource locations. - GenericXmlWebContextLoader: loads - a WebApplicationContext from - XML resource locations. + GenericXmlWebContextLoader: loads a + WebApplicationContext from XML + resource locations. @@ -1263,8 +1233,8 @@ public void testProcessRepeatedly() { The following sections explain how to configure the TestContext framework through annotations and - provide working examples of how to write unit and integration tests - with the framework. + provide working examples of how to write unit and integration tests with + the framework.
@@ -1288,10 +1258,10 @@ public void testProcessRepeatedly() { @Autowired ApplicationContext As an alternative to implementing the - ApplicationContextAware interface, - you can inject the application context for your test class through - the @Autowired annotation on either a - field or setter method. For example: + ApplicationContextAware interface, you + can inject the application context for your test class through the + @Autowired annotation on either a field + or setter method. For example: @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration @@ -1320,29 +1290,29 @@ public class MyWebAppTest { Dependency injection via @Autowired is provided by the - DependencyInjectionTestExecutionListener - which is configured by default (see ). + DependencyInjectionTestExecutionListener which + is configured by default (see ). Test classes that use the TestContext framework do not need to extend any particular class or implement a specific interface to - configure their application context. Instead, configuration is - achieved simply by declaring the + configure their application context. Instead, configuration is achieved + simply by declaring the @ContextConfiguration annotation at the - class level. If your test class does not explicitly declare - application context resource locations or annotated + class level. If your test class does not explicitly declare application + context resource locations or annotated classes, the configured ContextLoader determines how to load a context from a default location or default configuration classes. In - addition to context resource locations and - annotated classes, an application context can also - be configured via application context + addition to context resource locations and annotated + classes, an application context can also be + configured via application context initializers. The following sections explain how to configure an - ApplicationContext via XML - configuration files, annotated classes (typically + ApplicationContext via XML configuration + files, annotated classes (typically @Configuration classes), or context initializers using Spring's @ContextConfiguration annotation. @@ -1353,18 +1323,17 @@ public class MyWebAppTest {
Context configuration with XML resources - To load an ApplicationContext - for your tests using XML configuration files, annotate your test - class with @ContextConfiguration and + To load an ApplicationContext for + your tests using XML configuration files, annotate your test class + with @ContextConfiguration and configure the locations attribute with an array - that contains the resource locations of XML configuration metadata. - A plain or relative path — for example - "context.xml" — will be treated as a classpath - resource that is relative to the package in which the test class is - defined. A path starting with a slash is treated as an absolute - classpath location, for example - "/org/example/config.xml". A path which - represents a resource URL (i.e., a path prefixed with + that contains the resource locations of XML configuration metadata. A + plain or relative path — for example "context.xml" + — will be treated as a classpath resource that is relative to the + package in which the test class is defined. A path starting with a + slash is treated as an absolute classpath location, for example + "/org/example/config.xml". A path which represents + a resource URL (i.e., a path prefixed with classpath:, file:, http:, etc.) will be used as is. @@ -1377,13 +1346,13 @@ public class MyTest { // class body... } - @ContextConfiguration supports - an alias for the locations attribute through the - standard Java value attribute. Thus, if you do - not need to declare additional attributes in - @ContextConfiguration, you can omit - the declaration of the locations attribute name - and declare the resource locations by using the shorthand format + @ContextConfiguration supports an + alias for the locations attribute through the + standard Java value attribute. Thus, if you do not + need to declare additional attributes in + @ContextConfiguration, 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. @RunWith(SpringJUnit4ClassRunner.class) @@ -1396,12 +1365,11 @@ public class MyTest { value attributes from the @ContextConfiguration annotation, the TestContext framework will attempt to detect a default XML resource - location. Specifically, - GenericXmlContextLoader detects a default - location based on the name of the test class. If your class is named - com.example.MyTest, - GenericXmlContextLoader loads your - application context from + location. Specifically, GenericXmlContextLoader + detects a default location based on the name of the test class. If + your class is named com.example.MyTest, + GenericXmlContextLoader loads your application + context from "classpath:/com/example/MyTest-context.xml". package com.example; @@ -1418,11 +1386,11 @@ public class MyTest {
Context configuration with annotated classes - To load an ApplicationContext - for your tests using annotated classes (see - ), annotate your test class with - @ContextConfiguration and configure - the classes attribute with an array that contains + To load an ApplicationContext for + your tests using annotated classes (see ), annotate your test class with + @ContextConfiguration and configure the + classes attribute with an array that contains references to annotated classes. @RunWith(SpringJUnit4ClassRunner.class) @@ -1437,16 +1405,16 @@ public class MyTest { TestContext framework will attempt to detect the presence of default configuration classes. Specifically, AnnotationConfigContextLoader will detect all - static inner classes of the test class that meet the requirements - for configuration class implementations as specified in the Javadoc - for @Configuration. In the following - example, the OrderServiceTest class declares - a static inner configuration class named - Config that will be automatically used to - load the ApplicationContext for the - test class. Note that the name of the configuration class is - arbitrary. In addition, a test class can contain more than one - static inner configuration class if desired. + static inner classes of the test class that meet the requirements for + configuration class implementations as specified in the Javadoc for + @Configuration. In the following + example, the OrderServiceTest class declares a + static inner configuration class named Config + that will be automatically used to load the + ApplicationContext for the test class. + Note that the name of the configuration class is arbitrary. In + addition, a test class can contain more than one static inner + configuration class if desired. @RunWith(SpringJUnit4ClassRunner.class) // ApplicationContext will be loaded from the @@ -1480,19 +1448,18 @@ public class OrderServiceTest {
Mixing XML resources and annotated classes - It may sometimes be desirable to mix XML resources and - annotated classes (i.e., typically - @Configuration classes) to configure - an ApplicationContext for your tests. - For example, if you use XML configuration in production, you may - decide that you want to use - @Configuration classes to configure - specific Spring-managed components for your tests, or vice versa. As - mentioned in the TestContext - framework does not allow you to declare both - via @ContextConfiguration, but this - does not mean that you cannot use both. + It may sometimes be desirable to mix XML resources and annotated + classes (i.e., typically @Configuration + classes) to configure an + ApplicationContext for your tests. For + example, if you use XML configuration in production, you may decide + that you want to use @Configuration + classes to configure specific Spring-managed components for your + tests, or vice versa. As mentioned in the TestContext + framework does not allow you to declare both via + @ContextConfiguration, but this does + not mean that you cannot use both. If you want to use XML and @Configuration classes to configure @@ -1505,27 +1472,27 @@ public class OrderServiceTest { @ImportResource to import XML configuration files. Note that this behavior is semantically equivalent to how you configure your application in production: in - production configuration you will define either a set of XML - resource locations or a set of - @Configuration classes that your - production ApplicationContext will be - loaded from, but you still have the freedom to include or import the - other type of configuration. + production configuration you will define either a set of XML resource + locations or a set of @Configuration + classes that your production + ApplicationContext will be loaded from, + but you still have the freedom to include or import the other type of + configuration.
Context configuration with context initializers To configure an - ApplicationContext for your tests - using context initializers, annotate your test class with - @ContextConfiguration and configure - the initializers attribute with an array that - contains references to classes that implement + ApplicationContext for your tests using + context initializers, annotate your test class with + @ContextConfiguration and configure the + initializers attribute with an array that contains + references to classes that implement ApplicationContextInitializer. The declared context initializers will then be used to initialize the - ConfigurableApplicationContext that - is loaded for your tests. Note that the concrete + ConfigurableApplicationContext that is + loaded for your tests. Note that the concrete ConfigurableApplicationContext type supported by each declared initializer must be compatible with the type of ApplicationContext created by @@ -1533,9 +1500,8 @@ public class OrderServiceTest { typically a GenericApplicationContext). Furthermore, the order in which the initializers are invoked depends on whether they implement Spring's - Ordered interface or are annotated - with Spring's @Order - annotation. + Ordered interface or are annotated with + Spring's @Order annotation. @RunWith(SpringJUnit4ClassRunner.class) // ApplicationContext will be loaded from TestConfig @@ -1547,14 +1513,14 @@ public class MyTest { // class body... } - It is also possible to omit the declaration of XML - configuration files or annotated classes in + It is also possible to omit the declaration of XML configuration + files or annotated classes in @ContextConfiguration entirely and instead declare only ApplicationContextInitializer classes - which are then responsible for registering beans in the context — - for example, by programmatically loading bean definitions from XML - files or configuration classes. + which are then responsible for registering beans in the context — for + example, by programmatically loading bean definitions from XML files + or configuration classes. @RunWith(SpringJUnit4ClassRunner.class) // ApplicationContext will be initialized by EntireAppInitializer @@ -1570,36 +1536,35 @@ public class MyTest { @ContextConfiguration supports boolean inheritLocations and - inheritInitializers attributes that denote - whether resource locations or annotated classes and context - initializers declared by superclasses should be - inherited. The default value for both flags is - true. This means that a test class inherits the - resource locations or annotated classes as well as the context - initializers declared by any superclasses. Specifically, the - resource locations or annotated classes for a test class are - appended to the list of resource locations or annotated classes - declared by superclasses. Similarly, the initializers for a given - test class will be added to the set of initializers defined by test - superclasses. Thus, subclasses have the option of + inheritInitializers attributes that denote whether + resource locations or annotated classes and context initializers + declared by superclasses should be inherited. The + default value for both flags is true. This means + that a test class inherits the resource locations or annotated classes + as well as the context initializers declared by any superclasses. + Specifically, the resource locations or annotated classes for a test + class are appended to the list of resource locations or annotated + classes declared by superclasses. Similarly, the initializers for a + given test class will be added to the set of initializers defined by + test superclasses. Thus, subclasses have the option of extending the resource locations, annotated classes, or context initializers. If @ContextConfiguration's inheritLocations or inheritInitializers attribute is set to - false, the resource locations or annotated - classes and the context initializers, respectively, for the test - class shadow and effectively replace the - configuration defined by superclasses. + false, the resource locations or annotated classes + and the context initializers, respectively, for the test class + shadow and effectively replace the configuration + defined by superclasses. In the following example that uses XML resource locations, the ApplicationContext for ExtendedTest will be loaded from "base-config.xml" and - "extended-config.xml", in that order. Beans - defined in "extended-config.xml" may therefore + role="bold">and "extended-config.xml", + in that order. Beans defined in + "extended-config.xml" may therefore override (i.e., replace) those defined in "base-config.xml". @@ -1618,14 +1583,14 @@ public class ExtendedTest extends BaseTest { // class body... } - Similarly, in the following example that uses annotated - classes, the ApplicationContext for + Similarly, in the following example that uses annotated classes, + the ApplicationContext for ExtendedTest will be loaded from the - BaseConfig and ExtendedConfig - classes, in that order. Beans defined in - ExtendedConfig may therefore override (i.e., - replace) those defined in BaseConfig. + BaseConfig and + ExtendedConfig classes, in that order. Beans + defined in ExtendedConfig may therefore + override (i.e., replace) those defined in + BaseConfig. @RunWith(SpringJUnit4ClassRunner.class) // ApplicationContext will be loaded from BaseConfig @@ -1644,12 +1609,11 @@ public class ExtendedTest extends BaseTest { ApplicationContext for ExtendedTest will be initialized using BaseInitializer and - ExtendedInitializer. Note, however, that the - order in which the initializers are invoked depends on whether they - implement Spring's Ordered interface - or are annotated with Spring's @Order - annotation. + role="bold">and ExtendedInitializer. + Note, however, that the order in which the initializers are invoked + depends on whether they implement Spring's + Ordered interface or are annotated with + Spring's @Order annotation. @RunWith(SpringJUnit4ClassRunner.class) // ApplicationContext will be initialized by BaseInitializer @@ -1672,19 +1636,18 @@ public class ExtendedTest extends BaseTest { Spring 3.1 introduced first-class support in the framework for the notion of environments and profiles (a.k.a., bean definition profiles), and integration tests can be - configured to activate particular bean definition profiles for - various testing scenarios. This is achieved by annotating a test - class with the @ActiveProfiles - annotation and supplying a list of profiles that should be activated - when loading the ApplicationContext - for the test. + configured to activate particular bean definition profiles for various + testing scenarios. This is achieved by annotating a test class with + the @ActiveProfiles annotation and + supplying a list of profiles that should be activated when loading the + ApplicationContext for the test. @ActiveProfiles may be used with any implementation of the new SmartContextLoader SPI, but - @ActiveProfiles is not supported - with implementations of the older + @ActiveProfiles is not supported with + implementations of the older ContextLoader SPI. @@ -1746,25 +1709,23 @@ public class TransferServiceTest { } When TransferServiceTest is run, its - ApplicationContext will be loaded - from the app-config.xml configuration file in - the root of the classpath. If you inspect - app-config.xml you'll notice that the - accountRepository bean has a dependency on a - dataSource bean; however, + ApplicationContext will be loaded from + the app-config.xml configuration file in the root + of the classpath. If you inspect app-config.xml + you'll notice that the accountRepository bean has a + dependency on a dataSource bean; however, dataSource is not defined as a top-level bean. Instead, dataSource is defined twice: once in the production profile and once in the dev profile. By annotating TransferServiceTest with - @ActiveProfiles("dev") we instruct - the Spring TestContext Framework to load the + @ActiveProfiles("dev") we instruct the + Spring TestContext Framework to load the ApplicationContext with the active profiles set to {"dev"}. As a result, an embedded - database will be created, and the - accountRepository bean will be wired with a - reference to the development + database will be created, and the accountRepository + bean will be wired with a reference to the development DataSource. And that's likely what we want in an integration test. @@ -1887,23 +1848,21 @@ public class TransferServiceTest { @WebAppConfiguration. The presence of - @WebAppConfiguration on your test - class instructs the TestContext framework (TCF) that a + @WebAppConfiguration on your test class + instructs the TestContext framework (TCF) that a WebApplicationContext (WAC) should be loaded for your integration tests. In the background the TCF makes sure that a MockServletContext is - created and supplied to your test's WAC. By default the base - resource path for your - MockServletContext will be set to - "src/main/webapp". This is interpreted as a - path relative to the root of your JVM (i.e., normally the path to + created and supplied to your test's WAC. By default the base resource + path for your MockServletContext will + be set to "src/main/webapp". This is interpreted + as a path relative to the root of your JVM (i.e., normally the path to your project). If you're familiar with the directory structure of a web application in a Maven project, you'll know that - "src/main/webapp" is the default location for - the root of your WAR. If you need to override this default, simply - provide an alternate path to the - @WebAppConfiguration annotation - (e.g., + "src/main/webapp" is the default location for the + root of your WAR. If you need to override this default, simply provide + an alternate path to the + @WebAppConfiguration annotation (e.g., @WebAppConfiguration("src/test/webapp")). If you wish to reference a base resource path from the classpath instead of the file system, just use Spring's @@ -1912,9 +1871,9 @@ public class TransferServiceTest { Please note that Spring's testing support for WebApplicationContexts is on par with its support for standard - ApplicationContexts. When testing - with a WebApplicationContext you are - free to declare either XML configuration files or + ApplicationContexts. When testing with + a WebApplicationContext you are free to + declare either XML configuration files or @Configuration classes via @ContextConfiguration. You are of course also free to use any other test annotations such as @@ -1944,19 +1903,18 @@ public class WacTests { The above example demonstrates the TestContext framework's - support for convention over configuration. If - you annotate a test class with - @WebAppConfiguration without - specifying a resource base path, the resource path will effectively - default to "file:src/main/webapp". Similarly, - if you declare @ContextConfiguration - without specifying resource - locations, annotated - classes, or context + support for convention over configuration. If you + annotate a test class with + @WebAppConfiguration without specifying + a resource base path, the resource path will effectively default to + "file:src/main/webapp". Similarly, if you declare + @ContextConfiguration without + specifying resource locations, + annotated classes, or context initializers, Spring will attempt to detect the presence of your configuration using conventions (i.e., - "WacTests-context.xml" in the same package as - the WacTests class or static nested + "WacTests-context.xml" in the same package as the + WacTests class or static nested @Configuration classes). @@ -1976,13 +1934,13 @@ public class WacTests { This example demonstrates how to explicitly declare a resource - base path with @WebAppConfiguration - and an XML resource location with + base path with @WebAppConfiguration and + an XML resource location with @ContextConfiguration. The important - thing to note here is the different semantics for paths with these - two annotations. By default, - @WebAppConfiguration resource paths - are file system based; whereas, + thing to note here is the different semantics for paths with these two + annotations. By default, + @WebAppConfiguration resource paths are + file system based; whereas, @ContextConfiguration resource locations are classpath based. @@ -2012,13 +1970,13 @@ public class WacTests { To provide comprehensive web testing support, Spring 3.2 introduces a new - ServletTestExecutionListener that - is enabled by default. When testing against a + ServletTestExecutionListener that is + enabled by default. When testing against a WebApplicationContext this TestExecutionListener sets up default thread-local state via Spring Web's - RequestContextHolder before each - test method and creates a + RequestContextHolder before each test + method and creates a MockHttpServletRequest, MockHttpServletResponse, and ServletWebRequest based on the base @@ -2032,16 +1990,15 @@ public class WacTests { thread-local state. Once you have a - WebApplicationContext loaded for - your test you might find that you need to interact with the web - mocks — for example, to set up your test fixture or to perform - assertions after invoking your web component. The following - example demonstrates which mocks can be autowired into your test - instance. Note that the - WebApplicationContext and - MockServletContext are both cached - across the test suite; whereas, the other mocks are managed per - test method by the + WebApplicationContext loaded for your + test you might find that you need to interact with the web mocks — + for example, to set up your test fixture or to perform assertions + after invoking your web component. The following example + demonstrates which mocks can be autowired into your test instance. + Note that the WebApplicationContext + and MockServletContext are both + cached across the test suite; whereas, the other mocks are managed + per test method by the ServletTestExecutionListener. @@ -2074,19 +2031,19 @@ public class WacTests { Once the TestContext framework loads an ApplicationContext (or - WebApplicationContext) for a test, - that context will be cached and reused for WebApplicationContext) for a test, that + context will be cached and reused for all subsequent tests that declare the same - unique context configuration within the same test suite. To - understand how caching works, it is important to understand what is - meant by unique and test + unique context configuration within the same test suite. To understand + how caching works, it is important to understand what is meant by + unique and test suite. An ApplicationContext can be uniquely identified by the combination of configuration parameters that are used to load it. Consequently, the - unique combination of configuration parameters are used to generate - a key under which the context is cached. The + unique combination of configuration parameters are used to generate a + key under which the context is cached. The TestContext framework uses the following configuration parameters to build the context cache key: @@ -2102,8 +2059,8 @@ public class WacTests { - contextInitializerClasses - (from @ContextConfiguration) + contextInitializerClasses (from + @ContextConfiguration) @@ -2130,9 +2087,9 @@ public class WacTests { ApplicationContext and store it in a static context cache under a key that is based solely on those locations. So if TestClassB - also defines {"app-config.xml", - "test-config.xml"} for its locations (either explicitly or - implicitly through inheritance) but does not define + also defines {"app-config.xml", "test-config.xml"} + for its locations (either explicitly or implicitly through + inheritance) but does not define @WebAppConfiguration, a different ContextLoader, different active profiles, or different context initializers, then the same @@ -2145,23 +2102,22 @@ public class WacTests { Test suites and forked processes The Spring TestContext framework stores application contexts - in a static cache. This means that the - context is literally stored in a static - variable. In other words, if tests execute in separate processes - the static cache will be cleared between each test execution, and - this will effectively disable the caching mechanism. + in a static cache. This means that the context + is literally stored in a static variable. In + other words, if tests execute in separate processes the static cache + will be cleared between each test execution, and this will + effectively disable the caching mechanism. To benefit from the caching mechanism, all tests must run within the same process or test suite. This can be achieved by executing all tests as a group within an IDE. Similarly, when - executing tests with a build framework such as Ant, Maven, or - Gradle it is important to make sure that the build framework does - not fork between tests. For example, if the - fork between tests. For example, if the forkMode for the Maven Surefire plug-in is set to always - or pertest, the TestContext framework will not - be able to cache application contexts between test classes and the + or pertest, the TestContext framework will not be + able to cache application contexts between test classes and the build process will run significantly slower as a result. @@ -2169,13 +2125,13 @@ public class WacTests { 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 (see the discussion - of @DirtiesContext in ). This instructs + @DirtiesContext (see the discussion of + @DirtiesContext in ). This instructs Spring to remove the context from the cache and rebuild the - application context before executing the next test. Note that - support for the @DirtiesContext - annotation is provided by the + application context before executing the next test. Note that support + for the @DirtiesContext annotation is + provided by the DirtiesContextTestExecutionListener which is enabled by default.
@@ -2185,34 +2141,33 @@ public class WacTests { Dependency injection of test fixtures When you use the - DependencyInjectionTestExecutionListener — - 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 and 3.0, you can use Spring's - @Autowired annotation or the - @Inject annotation from JSR 300. + DependencyInjectionTestExecutionListener — 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 and + 3.0, you can use Spring's @Autowired + annotation or the @Inject annotation from + JSR 300. The TestContext framework does not instrument the manner in which a test instance is instantiated. Thus the use of @Autowired or - @Inject for constructors has no - effect for test classes. + @Inject for constructors has no effect + for test classes. Because @Autowired is used to - perform autowiring - by type , if you have multiple bean definitions of - the same type, you cannot rely on this approach for those particular - beans. In that case, you can use - @Autowired in conjunction with - @Qualifier. As of Spring 3.0 you may - also choose to use @Inject in + perform autowiring by + type , if you have multiple bean definitions of the + same type, you cannot rely on this approach for those particular beans. + In that case, you can use @Autowired in + conjunction with @Qualifier. As of Spring + 3.0 you may also choose to use @Inject in conjunction with @Named. Alternatively, if your test class has access to its ApplicationContext, you can perform an explicit @@ -2224,35 +2179,33 @@ public class WacTests { @Autowired or @Inject. Alternatively, you can disable dependency injection altogether by explicitly configuring your class - with @TestExecutionListeners and - omitting + with @TestExecutionListeners and omitting DependencyInjectionTestExecutionListener.class from the list of listeners. Consider the scenario of testing a HibernateTitleRepository class, as outlined in - the Goals section. - The next two code listings demonstrate the use of - @Autowired on fields and setter - methods. The application context configuration is presented after all - sample code listings. + the Goals section. The + next two code listings demonstrate the use of + @Autowired on fields and setter methods. + The application context configuration is presented after all sample code + listings. - The dependency injection behavior in the following code - listings is not specific to JUnit. The same DI techniques can be - used in conjunction with any testing framework. + The dependency injection behavior in the following code listings + is not specific to JUnit. The same DI techniques can be used in + conjunction with any testing framework. The following examples make calls to static assertion methods - such as assertNotNull() but without prepending - the call with Assert. In such cases, assume that - the method was properly imported through an import - static declaration that is not shown in the - example. + such as assertNotNull() but without prepending the + call with Assert. In such cases, assume that the + method was properly imported through an import + static declaration that is not shown in the example. The first code listing shows a JUnit-based implementation of the - test class that uses @Autowired for - field injection. + test class that uses @Autowired for field + injection. @RunWith(SpringJUnit4ClassRunner.class) // specifies the Spring configuration to load for this test fixture @@ -2319,10 +2272,10 @@ public class HibernateTitleRepositoryTests { </beans> - If you are extending from a Spring-provided test base class - that happens to use @Autowired on one - of its setter methods, you might have multiple beans of the affected - type defined in your application context: for example, multiple + If you are extending from a Spring-provided test base class that + happens to use @Autowired on one 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 method and use the @Qualifier annotation to indicate a @@ -2345,8 +2298,8 @@ public class HibernateTitleRepositoryTests { against <qualifier> declarations within the 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). + also point to a specific bean by name there (as shown above, assuming + that "myDataSource" is the bean id).
@@ -2354,10 +2307,10 @@ public class HibernateTitleRepositoryTests { Testing request and session scoped beans Request and session - scoped beans have been supported by Spring for several years - now, but it's always been a bit non-trivial to test them. As of Spring - 3.2 it's now a breeze to test your request-scoped and session-scoped - beans by following these steps. + scoped beans have been supported by Spring for several years now, + but it's always been a bit non-trivial to test them. As of Spring 3.2 + it's now a breeze to test your request-scoped and session-scoped beans + by following these steps.
@@ -2368,8 +2321,8 @@ public class HibernateTitleRepositoryTests { - Inject the mock request or session into your test instance - and prepare your test fixture as appropriate. + Inject the mock request or session into your test instance and + prepare your test fixture as appropriate. @@ -2384,13 +2337,13 @@ public class HibernateTitleRepositoryTests { The following code snippet displays the XML configuration for a - login use case. Note that the userService bean has - a dependency on a request-scoped loginAction bean. - Also, the LoginAction is instantiated using - SpEL expressions that retrieve the - username and password from the current HTTP request. In our test, we - will want to configure these request parameters via the mock managed - by the TestContext framework. + login use case. Note that the userService bean has a + dependency on a request-scoped loginAction bean. + Also, the LoginAction is instantiated using SpEL expressions that retrieve the username + and password from the current HTTP request. In our test, we will want to + configure these request parameters via the mock managed by the + TestContext framework. Request-scoped bean configuration @@ -2414,16 +2367,15 @@ public class HibernateTitleRepositoryTests { In RequestScopedBeanTests we inject both the UserService (i.e., the subject under test) and the MockHttpServletRequest into our test - instance. Within our requestScope() test method - we set up our test fixture by setting request parameters in the - provided MockHttpServletRequest. When the + instance. Within our requestScope() test method we + set up our test fixture by setting request parameters in the provided + MockHttpServletRequest. When the loginUser() method is invoked on our - userService we are assured that the user service - has access to the request-scoped loginAction for - the current MockHttpServletRequest (i.e., the - one we just set parameters in). We can then perform assertions against - the results based on the known inputs for the username and - password. + userService we are assured that the user service has + access to the request-scoped loginAction for the + current MockHttpServletRequest (i.e., the one we + just set parameters in). We can then perform assertions against the + results based on the known inputs for the username and password. Request-scoped bean test @@ -2449,14 +2401,14 @@ public class RequestScopedBeanTests { } - The following code snippet is similar to the one we saw above - for a request-scoped bean; however, this time the - userService bean has a dependency on a - session-scoped userPreferences bean. Note that the - UserPreferences bean is instantiated using a - SpEL expression that retrieves the theme from the - current HTTP session. In our test, we will need to configure a theme - in the mock session managed by the TestContext framework. + The following code snippet is similar to the one we saw above for + a request-scoped bean; however, this time the + userService bean has a dependency on a session-scoped + userPreferences bean. Note that the + UserPreferences bean is instantiated using a SpEL + expression that retrieves the theme from the + current HTTP session. In our test, we will need to configure a theme in + the mock session managed by the TestContext framework. Session-scoped bean configuration @@ -2484,11 +2436,10 @@ public class RequestScopedBeanTests { fixture by setting the expected "theme" attribute in the provided MockHttpSession. When the processUserPreferences() method is invoked on our - userService we are assured that the user service - has access to the session-scoped userPreferences - for the current MockHttpSession, and we can - perform assertions against the results based on the configured - theme. + userService we are assured that the user service has + access to the session-scoped userPreferences for the + current MockHttpSession, and we can perform + assertions against the results based on the configured theme. Session-scoped bean test @@ -2519,30 +2470,28 @@ public class SessionScopedBeanTests { In the TestContext framework, transactions are managed by the TransactionalTestExecutionListener. Note that - TransactionalTestExecutionListener is - configured by default, even if you do not explicitly declare + 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 application context loaded by @ContextConfiguration semantics. In - addition, you must declare - @Transactional either at the class or - method level for your tests. + addition, you must declare @Transactional + either at the class or method level for your tests. For class-level transaction configuration (i.e., setting an - explicit bean name for the transaction manager and the default - rollback flag), see the - @TransactionConfiguration entry in the - annotation + explicit bean name for the transaction manager and the default rollback + flag), see the @TransactionConfiguration + entry in the annotation support section. - If transactions are not enabled for the entire test class, you - can annotate methods explicitly with + If transactions are not enabled for the entire test class, you can + annotate methods explicitly with @Transactional. To control whether a - transaction should commit for a particular test method, you can use - the @Rollback annotation to override - the class-level default rollback setting. + transaction should commit for a particular test method, you can use the + @Rollback annotation to override the + class-level default rollback setting. AbstractTransactionalJUnit4SpringContextTests @@ -2553,14 +2502,13 @@ public class SessionScopedBeanTests { Occasionally you need to execute certain code before or after a 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 (if the test was configured not to roll back the - transaction). + example, to verify the initial database state prior to execution of your + test or to verify expected transactional commit behavior after test + execution (if the test was configured not to roll back the transaction). TransactionalTestExecutionListener supports the @BeforeTransaction and - @AfterTransaction annotations exactly - for such scenarios. Simply annotate any public void + @AfterTransaction annotations exactly for + such scenarios. Simply annotate any public void method in your test class with one of these annotations, and the TransactionalTestExecutionListener ensures that your before transaction method or after @@ -2569,12 +2517,11 @@ public class SessionScopedBeanTests { Any before methods (such as methods - annotated with JUnit's @Before) and - any after methods (such as methods annotated - with JUnit's @After) are executed - within a transaction. In addition, - methods annotated with - @BeforeTransaction or + annotated with JUnit's @Before) and any + after methods (such as methods annotated with + JUnit's @After) are executed within a transaction. In addition, methods + annotated with @BeforeTransaction or @AfterTransaction are naturally not executed for tests annotated with @NotTransactional. However, @@ -2623,21 +2570,21 @@ public class FictitiousTransactionalTest { } - + Avoid false positives when testing ORM code - 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 + 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. Note that this applies to JPA and any other - ORM frameworks that maintain an in-memory unit of + flushing the session. Note that this applies to JPA and any other ORM + frameworks that maintain an in-memory unit of work. // ... @@ -2688,9 +2635,9 @@ public void updateWithSessionFlush() { - applicationContext: Use this - variable to perform explicit bean lookups or to test the - state of the context as a whole. + applicationContext: Use this variable + to perform explicit bean lookups or to test the state of the + context as a whole. @@ -2698,29 +2645,28 @@ public void updateWithSessionFlush() { AbstractTransactionalJUnit4SpringContextTests: Abstract transactional extension of - AbstractJUnit4SpringContextTests that - also adds some convenience functionality for JDBC access. - Expects a javax.sql.DataSource bean and a - PlatformTransactionManager bean - to be defined in the ApplicationContext. - When you extend + AbstractJUnit4SpringContextTests that also + adds some convenience functionality for JDBC access. Expects a + javax.sql.DataSource bean and a + PlatformTransactionManager bean to + be defined in the ApplicationContext. When + you extend AbstractTransactionalJUnit4SpringContextTests - you can access the following protected - instance variables: + you can access the following protected instance + variables: applicationContext: Inherited from the AbstractJUnit4SpringContextTests - superclass. Use this variable to perform explicit bean - lookups or to test the state of the context as a - whole. + superclass. Use this variable to perform explicit bean lookups + or to test the state of the context as a whole. jdbcTemplate: Use this variable to - execute SQL statements to query the database. Such queries - can be used to confirm database state both prior + execute SQL statements to query the database. Such queries can + be used to confirm database state both prior to and after execution of database-related application code, and Spring ensures that such queries run in the scope of the same transaction as the @@ -2737,8 +2683,8 @@ 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 directly extend the class - you are testing — you can configure your own custom test classes - by using + you are testing — you can configure your own custom test classes by + using @RunWith(SpringJUnit4ClassRunner.class), @ContextConfiguration, @TestExecutionListeners, and so @@ -2752,18 +2698,17 @@ public void updateWithSessionFlush() { The Spring TestContext Framework offers full integration with JUnit 4.5+ through a custom runner (tested on JUnit 4.5 – 4.10). By annotating test classes with - @RunWith(SpringJUnit4ClassRunner.class), - developers can implement standard JUnit-based unit and integration - tests and simultaneously reap the benefits of the TestContext - framework such as support for loading application contexts, - dependency injection of test instances, transactional test method - execution, and so on. The following code listing displays the - minimal requirements for configuring a test class to run with the - custom Spring Runner. + @RunWith(SpringJUnit4ClassRunner.class), developers + can implement standard JUnit-based unit and integration tests and + simultaneously reap the benefits of the TestContext framework such as + support for loading application contexts, dependency injection of test + instances, transactional test method execution, and so on. The + following code listing displays the minimal requirements for + configuring a test class to run with the custom Spring Runner. @TestExecutionListeners is configured with an empty list in order to disable the default listeners, which - otherwise would require an ApplicationContext to be configured - through @ContextConfiguration. + otherwise would require an ApplicationContext to be configured through + @ContextConfiguration. @RunWith(SpringJUnit4ClassRunner.class) @TestExecutionListeners({}) @@ -2797,9 +2742,9 @@ public class SimpleTest { - applicationContext: Use this - variable to perform explicit bean lookups or to test the - state of the context as a whole. + applicationContext: Use this variable + to perform explicit bean lookups or to test the state of the + context as a whole. @@ -2807,29 +2752,28 @@ public class SimpleTest { AbstractTransactionalTestNGSpringContextTests: Abstract transactional extension of - AbstractTestNGSpringContextTests that - adds some convenience functionality for JDBC access. Expects a + AbstractTestNGSpringContextTests that adds + some convenience functionality for JDBC access. Expects a javax.sql.DataSource bean and a - PlatformTransactionManager bean - to be defined in the ApplicationContext. - When you extend + PlatformTransactionManager bean to + be defined in the ApplicationContext. When + you extend AbstractTransactionalTestNGSpringContextTests, - you can access the following protected - instance variables: + you can access the following protected instance + variables: applicationContext: Inherited from the AbstractTestNGSpringContextTests - superclass. Use this variable to perform explicit bean - lookups or to test the state of the context as a - whole. + superclass. Use this variable to perform explicit bean lookups + or to test the state of the context as a whole. jdbcTemplate: Use this variable to - execute SQL statements to query the database. Such queries - can be used to confirm database state both prior + execute SQL statements to query the database. Such queries can + be used to confirm database state both prior to and after execution of database-related application code, and Spring ensures that such queries run in the scope of the same transaction as the @@ -2846,8 +2790,8 @@ public class SimpleTest { 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 directly extend the class - you are testing — you can configure your own custom test classes - by using @ContextConfiguration, + you are testing — you can configure your own custom test classes by + using @ContextConfiguration, @TestExecutionListeners, and so on, and by manually instrumenting your test class with a TestContextManager. See the source code of @@ -2873,71 +2817,70 @@ public class SimpleTest { xl:href="https://github.com/SpringSource/spring-test-mvc">spring-test-mvc project is still available on GitHub and can be used in conjunction with Spring Framework 3.1.x. Applications upgrading to 3.2 - should replace the spring-test-mvc dependency - with a dependency on spring-test. + should replace the spring-test-mvc dependency with + a dependency on spring-test. The spring-test module uses a different package org.springframework.test.web but otherwise is nearly identical with two exceptions. One is support for - features new in 3.2 (e.g. asynchronous web requests). The other - relates to the options for creating a MockMvc - instance. In Spring Framework 3.2, this can only be done through the - TestContext framework, which provides caching benefits for the loaded + features new in 3.2 (e.g. asynchronous web requests). The other relates + to the options for creating a MockMvc instance. + In Spring Framework 3.2, this can only be done through the TestContext + framework, which provides caching benefits for the loaded configuration. The Spring MVC Test framework provides first class JUnit support for testing client and server-side Spring MVC code through a fluent API. Typically it loads the actual Spring configuration - through the TestContext framework and always uses - the DispatcherServlet to process requests thus + through the TestContext framework and always uses the + DispatcherServlet to process requests thus approximating full integration tests without requiring a running Servlet container. - Client-side tests are RestTemplate-based - and allow tests for code that relies on the - RestTemplate without requiring a running server - to respond to the requests. + Client-side tests are RestTemplate-based and + allow tests for code that relies on the + RestTemplate without requiring a running server to + respond to the requests.
Server-Side Tests - Before Spring Framework 3.2, the most likely way to test a - Spring MVC controller was to write a unit test that instantiates the + Before Spring Framework 3.2, the most likely way to test a Spring + MVC controller was to write a unit test that instantiates the controller, injects it with mock or stub dependencies, and then calls its methods directly, using a MockHttpServletRequest and MockHttpServletResponse where necessary. Although this is pretty easy to do, controllers have many - annotations, and much remains untested. Request mappings, data - binding, type conversion, and validation are just a few examples of - what isn't tested. Furthermore, there are other types of annotated - methods such as @InitBinder, + annotations, and much remains untested. Request mappings, data binding, + type conversion, and validation are just a few examples of what isn't + tested. Furthermore, there are other types of annotated methods such as + @InitBinder, @ModelAttribute, and @ExceptionHandler that get invoked as part of request processing. The idea behind Spring MVC Test is to be able to re-write those - controller tests by performing actual requests and generating - responses, as they would be at runtime, along the way invoking - controllers through the Spring MVC - DispatcherServlet. Controllers can still be - injected with mock dependencies, so tests can remain focused on the - web layer. + controller tests by performing actual requests and generating responses, + as they would be at runtime, along the way invoking controllers through + the Spring MVC DispatcherServlet. Controllers can + still be injected with mock dependencies, so tests can remain focused on + the web layer. Spring MVC Test builds on the familiar "mock" implementations of the Servlet API available in the spring-test - module. This allows performing requests and generating responses - without the need for running in a Servlet container. For the most part + module. This allows performing requests and generating responses without + the need for running in a Servlet container. For the most part everything should work as it does at runtime with the exception of JSP rendering, which is not available outside a Servlet container. Furthermore, if you are familiar with how the MockHttpServletResponse works, you'll know that forwards and redirects are not actually executed. Instead "forwarded" - and "redirected" URLs are saved and can be asserted in tests. This - means if you are using JSPs, you can verify the JSP page to which the - request was forwarded. + and "redirected" URLs are saved and can be asserted in tests. This means + if you are using JSPs, you can verify the JSP page to which the request + was forwarded. All other means of rendering including @ResponseBody methods and @@ -2980,18 +2923,17 @@ public class ExampleTests { The test relies on the WebApplicationContext support of the TestContext framework. It loads Spring - configuration from an XML configuration file located in the same - package as the test class (also supports JavaConfig) and injects the - created WebApplicationContext into the - test so a MockMvc instance can be created with - it. + configuration from an XML configuration file located in the same package + as the test class (also supports JavaConfig) and injects the created + WebApplicationContext into the test so a + MockMvc instance can be created with it. The MockMvc is then used to perform a request to "/accounts/1" and verify the resulting response status is 200, the response content type is - "application/json", and response content has a - JSON property called "name" with the value "Lee". JSON content is - inspected with the help of Jayway's "application/json", and response content has a JSON + property called "name" with the value "Lee". JSON content is inspected + with the help of Jayway's JsonPath project. There are lots of other options for verifying the result of the performed request and those will be discussed later. @@ -3004,13 +2946,13 @@ public class ExampleTests { MockMvcResultMatchers.*, and MockMvcBuilders.*. An easy way to find these classes is to search for types matching - "MockMvc*". If using Eclipse, be sure to add - them as "favorite static members" in the Eclipse preferences under + "MockMvc*". If using Eclipse, be sure to add them + as "favorite static members" in the Eclipse preferences under Java -> Editor -> Content Assist -> Favorites. That will allow use of content assist after - typing the first character of the static method name. Other IDEs - (e.g. IntelliJ) may not require any additional configuration. Just - check the support for code completion on static members. + typing the first character of the static method name. Other IDEs (e.g. + IntelliJ) may not require any additional configuration. Just check the + support for code completion on static members.
@@ -3020,11 +2962,11 @@ public class ExampleTests { MockMvc that can be used to perform requests. There are two main options. - The first option is to point to Spring MVC configuration - through the TestContext framework, which loads - the Spring configuration and injects a - WebApplicationContext into the test - to use to create a MockMvc: + The first option is to point to Spring MVC configuration through + the TestContext framework, which loads the Spring + configuration and injects a + WebApplicationContext into the test to + use to create a MockMvc: @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @@ -3048,9 +2990,9 @@ public class MyWebTests { The second option is to simply register a controller instance without loading any Spring configuration. Instead basic Spring MVC configuration suitable for testing annotated controllers is - automatically created. The created configuration is comparable to - that of the MVC JavaConfig (and the MVC namespace) and can be - customized to a degree through builder-style methods: + automatically created. The created configuration is comparable to that + of the MVC JavaConfig (and the MVC namespace) and can be customized to + a degree through builder-style methods: public class MyWebTests { @@ -3069,20 +3011,20 @@ public class MyWebTests { The "webAppContextSetup" loads the actual Spring MVC configuration resulting in a more complete integration - test. Since the TestContext framework caches - the loaded Spring configuration, it helps to keep tests running fast - even as more tests get added. Furthermore, you can inject mock - services into controllers through Spring configuration, in order to - remain focused on testing the web layer. Here is an example of - declaring a mock service with Mockito: + test. Since the TestContext framework caches the + loaded Spring configuration, it helps to keep tests running fast even + as more tests get added. Furthermore, you can inject mock services + into controllers through Spring configuration, in order to remain + focused on testing the web layer. Here is an example of declaring a + mock service with Mockito: <bean id="accountService" class="org.mockito.Mockito" factory-method="mock"> <constructor-arg value="org.example.AccountService"/> </bean> - Then you can inject the mock service into the test in order - set up and verify expectations: + Then you can inject the mock service into the test in order set + up and verify expectations: @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @@ -3101,19 +3043,19 @@ public class AccountTests { } - The "standaloneSetup" on the other hand - is a little closer to a unit test. It tests one controller at a - time, the controller can be injected with mock dependencies - manually, and it doesn't involve loading Spring configuration. Such - tests are more focused in style and make it easier to see which - controller is being tested, whether any specific Spring MVC - configuration is required to work, and so on. The "standaloneSetup" - is also a very convenient way to write ad-hoc tests to verify some - behavior or to debug an issue. - - Just like with integration vs unit testing, there is no right - or wrong answer. Using the "standaloneSetup" does imply the need for - some additional "webAppContextSetup" tests to verify the Spring MVC + The "standaloneSetup" on the other hand is + a little closer to a unit test. It tests one controller at a time, the + controller can be injected with mock dependencies manually, and it + doesn't involve loading Spring configuration. Such tests are more + focused in style and make it easier to see which controller is being + tested, whether any specific Spring MVC configuration is required to + work, and so on. The "standaloneSetup" is also a very convenient way + to write ad-hoc tests to verify some behavior or to debug an + issue. + + Just like with integration vs unit testing, there is no right or + wrong answer. Using the "standaloneSetup" does imply the need for some + additional "webAppContextSetup" tests to verify the Spring MVC configuration. Alternatively, you can decide write all tests with "webAppContextSetup" and always test against actual Spring MVC configuration. @@ -3151,22 +3093,21 @@ public class AccountTests { doesn't check the query string, as is most often the case, then it doesn't matter how parameters are added. Keep in mind though that parameters provided in the URI template will be decoded while - parameters provided through the param(...) - method are expected to be decoded. + parameters provided through the param(...) method + are expected to be decoded. - In most cases it's preferable to leave out the context path - and the Servlet path from the request URI. If you must test with the - full request URI, be sure to set the - contextPath and - servletPath accordingly so that request - mappings will work: + In most cases it's preferable to leave out the context path and + the Servlet path from the request URI. If you must test with the full + request URI, be sure to set the contextPath and + servletPath accordingly so that request mappings + will work: mockMvc.perform(get("/app/main/hotels/{id}").contextPath("/app").servletPath("/main")) - Looking at the above example, it would be cumbersome to set - the contextPath and servletPath with every performed request. That's - why you can define default request properties when building the + Looking at the above example, it would be cumbersome to set the + contextPath and servletPath with every performed request. That's why + you can define default request properties when building the MockMvc: public class MyWebTests { @@ -3185,10 +3126,10 @@ public class AccountTests { The above properties will apply to every request performed through the MockMvc. If the same property is - also specified on a given request, it will override the default - value. That is why, the HTTP method and URI don't matter, when - setting default request properties, since they must be specified on - every request. + also specified on a given request, it will override the default value. + That is why, the HTTP method and URI don't matter, when setting + default request properties, since they must be specified on every + request.
@@ -3203,12 +3144,12 @@ public class AccountTests { MockMvcResultMatchers.* defines a number of static members, some of which return types with additional methods, - for asserting the result of the performed request. The assertions - fall in two general categories. + for asserting the result of the performed request. The assertions fall + in two general categories. The first category of assertions verify properties of the - response, i.e the response status, headers, and content. Those are - the most important things to test for. + response, i.e the response status, headers, and content. Those are the + most important things to test for. The second category of assertions go beyond the response, and allow inspecting Spring MVC specific constructs such as which @@ -3216,8 +3157,8 @@ public class AccountTests { raised and handled, what the content of the model is, what view was selected, what flash attributes were added, and so on. It is also possible to verify Servlet specific constructs such as request and - session attributes. The following test asserts that - binding/validation failed: + session attributes. The following test asserts that binding/validation + failed: mockMvc.perform(post("/persons")) @@ -3225,8 +3166,8 @@ mockMvc.perform(post("/persons")) .andExpect(model().attributeHasErrors("person")); - Many times when writing tests, it's useful to dump the result - of the performed request. This can be done as follows, where + Many times when writing tests, it's useful to dump the result of + the performed request. This can be done as follows, where print() is a static import from MockMvcResultHandlers: @@ -3235,8 +3176,8 @@ mockMvc.perform(post("/persons")) .andExpect(status().isOk()) .andExpect(model().attributeHasErrors("person")); - As long as request processing causes an unhandled exception, - the print() method will print all the available + As long as request processing causes an unhandled exception, the + print() method will print all the available result data to System.out. In some cases, you may want to get direct access to the result @@ -3247,8 +3188,8 @@ mockMvc.perform(post("/persons")) MvcResult mvcResult = mockMvc.perform(post("/persons")).andExpect(status().isOk()).andReturn(); // ... - When all tests repeat the same expectations, you can define - the common expectations once when building the + When all tests repeat the same expectations, you can define the + common expectations once when building the MockMvc: standaloneSetup(new SimpleController()) @@ -3256,8 +3197,8 @@ mockMvc.perform(post("/persons")) .alwaysExpect(content().contentType("application/json;charset=UTF-8")) .build() - Note that the expectation is always - applied and cannot be overridden without creating a separate + Note that the expectation is always applied + and cannot be overridden without creating a separate MockMvc instance. When JSON response content contains hypermedia links created @@ -3268,9 +3209,8 @@ mockMvc.perform(post("/persons")) mockMvc.perform(get("/people").accept(MediaType.APPLICATION_JSON)) .andExpect(jsonPath("$.links[?(@.rel == 'self')].href").value("http://localhost:8080/people")); - When XML response content contains hypermedia links created - with Spring + When XML response content contains hypermedia links created with + Spring HATEOAS, the resulting links can be verified: Map<String, String> ns = Collections.singletonMap("ns", "http://www.w3.org/2005/Atom"); @@ -3289,8 +3229,8 @@ mockMvc.perform(get("/handle").accept(MediaType.APPLICATION_XML)) Registered filters will be invoked through MockFilterChain from - spring-test and the last filter will delegates - to the DispatcherServlet. + spring-test and the last filter will delegates to + the DispatcherServlet.
@@ -3321,36 +3261,34 @@ mockServer.expect(requestTo("/greeting")).andRespond(withSuccess("Hello world", mockServer.verify(); - In the above example, - MockRestServiceServer -- the central class for - client-side REST tests -- configures the + In the above example, MockRestServiceServer + -- the central class for client-side REST tests -- configures the RestTemplate with a custom ClientHttpRequestFactory that asserts actual requests against expectations and returns "stub" responses. In - this case we expect a single request to "/greeting" and want to return - a 200 response with "text/plain" content. We could define as many + this case we expect a single request to "/greeting" and want to return a + 200 response with "text/plain" content. We could define as many additional requests and stub responses as necessary. Once expected requests and stub responses have been defined, the RestTemplate can be used in client-side code as usual. At the end of the tests mockServer.verify() - can be used to verify that all expected requests were - performed. + can be used to verify that all expected requests were performed.
Static Imports - Just like with server-side tests, the fluent API for - client-side tests requires a few static imports. Those are easy to - find by searching "MockRest*". Eclipse users - should add "MockRestRequestMatchers.*" and + Just like with server-side tests, the fluent API for client-side + tests requires a few static imports. Those are easy to find by + searching "MockRest*". Eclipse users should add + "MockRestRequestMatchers.*" and "MockRestResponseCreators.*" as "favorite - static members" in the Eclipse preferences under Java - -> Editor -> Content Assist -> Favorites. That - allows using content assist after typing the first character of the - static method name. Other IDEs (e.g. IntelliJ) may not require any - additional configuration. Just check the support for code completion - on static members. + static members" in the Eclipse preferences under Java -> + Editor -> Content Assist -> Favorites. That allows + using content assist after typing the first character of the static + method name. Other IDEs (e.g. IntelliJ) may not require any additional + configuration. Just check the support for code completion on static + members.
@@ -3368,11 +3306,10 @@ mockServer.verify(); 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 - AbstractClinicTests, for which a partial listing - is shown below: + several features of the Spring TestContext Framework + in a JUnit 4.5+ environment. Most test functionality is included in the + AbstractClinicTests, for which a partial listing is + shown below: import static org.junit.Assert.assertEquals; // import ... @@ -3439,10 +3376,9 @@ public abstract class AbstractClinicTests extends Abstract The PetClinic application supports three data access technologies: JDBC, Hibernate, and JPA. By declaring - @ContextConfiguration without any - specific resource locations, the - AbstractClinicTests class will have its - application context loaded from the default location, + @ContextConfiguration without any specific + resource locations, the AbstractClinicTests class + will have its application context loaded from the default location, AbstractClinicTests-context.xml, which declares a common DataSource. Subclasses specify additional context locations that must declare a @@ -3451,8 +3387,8 @@ public abstract class AbstractClinicTests extends Abstract For example, the Hibernate implementation of the PetClinic tests contains the following implementation. For this example, - HibernateClinicTests does not contain a single - line of code: we only need to declare + HibernateClinicTests does not contain a single line + of code: we only need to declare @ContextConfiguration, and the tests are inherited from AbstractClinicTests. Because @ContextConfiguration is declared without @@ -3474,8 +3410,8 @@ public class HibernateClinicTests extends AbstractClinicTests { } 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 - SessionFactory in the case of an application - using Hibernate. + SessionFactory in the case of an application using + Hibernate. As far as possible, you should have exactly the same Spring configuration files in your integration tests as in the deployed @@ -3491,12 +3427,11 @@ public class HibernateClinicTests extends AbstractClinicTests { } combination like the Commons DBCP BasicDataSource and DataSourceTransactionManager or HibernateTransactionManager for them. You can - factor out this variant behavior into a single XML file, having the - 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 - example. + factor out this variant behavior into a single XML file, having the 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 example.
@@ -3522,8 +3457,8 @@ public class HibernateClinicTests extends AbstractClinicTests { } MockObjects.com: Web site - dedicated to mock objects, a technique for improving the design of - code within test-driven development. + dedicated to mock objects, a technique for improving the design of code + within test-driven development. @@ -3533,16 +3468,15 @@ public class HibernateClinicTests extends AbstractClinicTests { } EasyMock: Java - library that provides Mock Objects for interfaces - (and objects through the class extension) by generating them on the - fly using Java's proxy mechanism. Used by the - Spring Framework in its test suite. + library that provides Mock Objects for interfaces (and + objects through the class extension) by generating them on the fly using + Java's proxy mechanism. Used by the Spring Framework + in its test suite. JMock: Library that - supports test-driven development of Java code with mock - objects. + supports test-driven development of Java code with mock objects.