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].
|