156 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| [[integration-testing]]
 | |
| = Integration Testing
 | |
| 
 | |
| It is important to be able to perform some integration testing without requiring
 | |
| deployment to your application server or connecting to other enterprise infrastructure.
 | |
| Doing so lets you test things such as:
 | |
| 
 | |
| * The correct wiring of your Spring IoC container contexts.
 | |
| * Data access using JDBC or an ORM tool. This can include such things as the correctness
 | |
|   of SQL statements, Hibernate queries, JPA entity mappings, and so forth.
 | |
| 
 | |
| 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 xref:core/beans/dependencies.adoc[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 Selenium tests or
 | |
| remote tests that rely on deployment to an application server.
 | |
| 
 | |
| Unit and integration testing support is provided in the form of the annotation-driven
 | |
| xref:testing/testcontext-framework.adoc[Spring TestContext Framework]. The TestContext framework is
 | |
| agnostic of the actual testing framework in use, which allows instrumentation of tests
 | |
| in various environments, including JUnit, TestNG, and others.
 | |
| 
 | |
| The following section provides an overview of the high-level goals of Spring's
 | |
| integration support, and the rest of this chapter then focuses on dedicated topics:
 | |
| 
 | |
| * xref:testing/support-jdbc.adoc[JDBC Testing Support]
 | |
| * xref:testing/testcontext-framework.adoc[Spring TestContext Framework]
 | |
| * xref:testing/webtestclient.adoc[WebTestClient]
 | |
| * xref:testing/mockmvc.adoc[MockMvc]
 | |
| * xref:testing/spring-mvc-test-client.adoc[Testing Client Applications]
 | |
| * xref:testing/annotations.adoc[Annotations]
 | |
| 
 | |
| 
 | |
| 
 | |
| [[integration-testing-goals]]
 | |
| == Goals of Integration Testing
 | |
| 
 | |
| Spring's integration testing support has the following primary goals:
 | |
| 
 | |
| * To manage xref:testing/integration.adoc#testing-ctx-management[Spring IoC container caching] between tests.
 | |
| * To provide xref:testing/integration.adoc#testing-fixture-di[Dependency Injection of test fixture instances].
 | |
| * To provide xref:testing/integration.adoc#testing-tx[transaction management] appropriate to integration testing.
 | |
| * To supply xref:testing/integration.adoc#testing-support-classes[Spring-specific base classes] that assist
 | |
|   developers in writing integration tests.
 | |
| 
 | |
| The next few sections describe each goal and provide links to implementation and
 | |
| configuration details.
 | |
| 
 | |
| 
 | |
| [[testing-ctx-management]]
 | |
| === Context Management and Caching
 | |
| 
 | |
| The Spring TestContext Framework provides consistent loading of Spring
 | |
| `ApplicationContext` instances and `WebApplicationContext` instances 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.
 | |
| 
 | |
| Test classes typically declare either an array of resource locations for XML or Groovy
 | |
| configuration metadata -- often in the classpath -- or an array of component 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 configuration files for production
 | |
| deployments.
 | |
| 
 | |
| By default, once loaded, the configured `ApplicationContext` is reused for each test.
 | |
| Thus, the setup cost is incurred only once per test suite, and subsequent test execution
 | |
| is much faster. In this context, the term "`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.
 | |
| 
 | |
| See xref:testing/testcontext-framework/ctx-management.adoc[Context Management] and xref:testing/testcontext-framework/ctx-management/caching.adoc[Context Caching] with the
 | |
| TestContext framework.
 | |
| 
 | |
| 
 | |
| [[testing-fixture-di]]
 | |
| === Dependency Injection of Test Fixtures
 | |
| 
 | |
| When the TestContext framework loads your application context, it can optionally
 | |
| configure instances of your test classes by using Dependency Injection. This provides a
 | |
| convenient mechanism for setting up test fixtures by using preconfigured beans from your
 | |
| application context. A strong benefit here is that you can reuse application contexts
 | |
| across various testing scenarios (for example, for configuring Spring-managed object
 | |
| graphs, transactional proxies, `DataSource` instances, and others), thus avoiding the
 | |
| need to duplicate complex test fixture setup for individual test cases.
 | |
| 
 | |
| As an example, consider a scenario where we have a class (`HibernateTitleRepository`)
 | |
| that implements data access logic for a `Title` domain entity. We want to write
 | |
| integration tests that test the following areas:
 | |
| 
 | |
| * 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 place?
 | |
| * The logic of the `HibernateTitleRepository`: Does the configured instance of this class
 | |
|   perform as anticipated?
 | |
| 
 | |
| See dependency injection of test fixtures with the
 | |
| xref:testing/testcontext-framework/fixture-di.adoc[TestContext framework].
 | |
| 
 | |
| 
 | |
| [[testing-tx]]
 | |
| === Transaction Management
 | |
| 
 | |
| One common issue in tests that access a real database is their effect on the state of the
 | |
| persistence store. Even when you use 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 of a transaction.
 | |
| 
 | |
| The TestContext framework addresses this issue. By default, the framework creates and
 | |
| rolls back a transaction for each test. You can write code that can assume the existence
 | |
| of a transaction. If you call transactionally proxied objects in your tests, they 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 rolls back by default, and the database returns to
 | |
| its state prior to execution of the test. Transactional support is provided to a test by
 | |
| using 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 database), you can tell the TestContext
 | |
| framework to cause the transaction to commit instead of roll back by using the
 | |
| xref:testing/annotations.adoc[`@Commit`] annotation.
 | |
| 
 | |
| See transaction management with the xref:testing/testcontext-framework/tx.adoc[TestContext framework].
 | |
| 
 | |
| 
 | |
| [[testing-support-classes]]
 | |
| === 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 let you access:
 | |
| 
 | |
| * The `ApplicationContext`, for performing explicit bean lookups or testing the state of
 | |
|   the context as a whole.
 | |
| * A `JdbcTemplate`, for executing SQL statements to query the database. You can use such
 | |
|   queries to confirm database state both before 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 xref:testing/testcontext-framework/tx.adoc#testcontext-tx-false-positives[false positives].
 | |
| 
 | |
| In addition, you may want to create your own custom, application-wide superclass with
 | |
| instance variables and methods specific to your project.
 | |
| 
 | |
| See support classes for the xref:testing/testcontext-framework/support-classes.adoc[TestContext framework].
 |