The Spring Framework provides the following set of Spring-specific annotations that you can use in your unit and integration tests in conjunction with the TestContext framework.
Spring’s testing annotations include the following:
@BootstrapWith
@ContextConfiguration
@WebAppConfiguration
@ContextHierarchy
@ActiveProfiles
@TestPropertySource
@DirtiesContext
@TestExecutionListeners
@Commit
@Rollback
@BeforeTransaction
@AfterTransaction
@Sql
@SqlConfig
@SqlGroup
@BootstrapWith
@BootstrapWith
is a class-level annotation that you can use to configure how the Spring TestContext Framework is bootstrapped. Specifically, you can use @BootstrapWith
to specify a custom TestContextBootstrapper
.
@ContextConfiguration
@ContextConfiguration
defines class-level metadata that is used to determine how to load and configure an ApplicationContext
for integration tests. Specifically, @ContextConfiguration
declares the application context resource locations
or the annotated classes
used to load the context.
Resource locations are typically XML configuration files or Groovy scripts located in the classpath, while annotated classes are typically @Configuration
classes. However, resource locations can also refer to files and scripts in the file system, and annotated classes can be component classes, and so on. The following example shows a @ContextConfiguration
annotation that refers to an XML file:
@ContextConfiguration("/test-config.xml") public class XmlApplicationContextTests { // class body... }
The following example shows a @ContextConfiguration
annotation that refers to a class:
@ContextConfiguration(classes = TestConfig.class) public class ConfigClassApplicationContextTests { // class body... }
As an alternative or in addition to declaring resource locations or annotated classes, you can use @ContextConfiguration
to declare ApplicationContextInitializer
classes. The following example shows such a case:
@ContextConfiguration(initializers = CustomContextIntializer.class) public class ContextInitializerTests { // class body... }
You can optionally use @ContextConfiguration
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 initializers
and either resource locations
or annotated classes
. The following example uses both a location and a loader:
@ContextConfiguration(locations = "/test-context.xml", loader = CustomContextLoader.class) public class CustomLoaderXmlApplicationContextTests { // class body... }
@WebAppConfiguration
@WebAppConfiguration
is a class-level annotation that you can use to declare that the ApplicationContext
loaded for an integration test should be a WebApplicationContext
. The mere presence of @WebAppConfiguration
on a test class ensures that aWebApplicationContext
is loaded for the test, using the default value of "file:src/main/webapp"
for the path to the root of the web application (that is, the resource base path). The resource base path is used behind the scenes to create aMockServletContext
, which serves as the ServletContext
for the test’s WebApplicationContext
. The following example shows how to use the @WebAppConfiguration
annotation:
@ContextConfiguration @WebAppConfiguration public class WebAppTests { // class body... }
To override the default, you can specify a different base resource path by using 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. The following example shows how to specify a classpath resource:
@ContextConfiguration @WebAppConfiguration("classpath:test-web-resources") 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.
@ContextHierarchy
@ContextHierarchy
is a class-level annotation that is used to define a hierarchy of ApplicationContext
instances for integration tests. @ContextHierarchy
should be declared with a list of one or more @ContextConfiguration
instances, each of which defines a level in the context hierarchy. The following examples demonstrate the use of @ContextHierarchy
within a single test class (@ContextHierarchy
can also be used within a test class hierarchy):
@ContextHierarchy({ @ContextConfiguration("/parent-config.xml"), @ContextConfiguration("/child-config.xml") }) public class ContextHierarchyTests { // class body... }
@WebAppConfiguration @ContextHierarchy({ @ContextConfiguration(classes = AppConfig.class), @ContextConfiguration(classes = WebConfig.class) }) public class WebIntegrationTests { // class body... }
@ActiveProfiles
@ActiveProfiles
is a class-level annotation that is used to declare which bean definition profiles should be active when loading an ApplicationContext
for an integration test. The following example indicates that the dev
profile should be active:
@ContextConfiguration @ActiveProfiles("dev") public class DeveloperTests { // class body... }
The following example indicates that both the dev
and the integration
profiles should be active:
@ContextConfiguration @ActiveProfiles({"dev", "integration"}) public class DeveloperIntegrationTests { // class body... }
@TestPropertySource
@TestPropertySource
is a class-level annotation that you can use to configure the locations of properties files and inlined properties to be added to the set of PropertySources
in the Environment
for an ApplicationContext
loaded for an integration test.
Test property sources have higher precedence than those loaded from the operating system’s environment or Java system properties as well as property sources added by the application declaratively through @PropertySource
or programmatically. Thus, test property sources can be used to selectively override properties defined in system and application property sources. Furthermore, inlined properties have higher precedence than properties loaded from resource locations. The following example demonstrates how to declare a properties file from the classpath:
@ContextConfiguration @TestPropertySource("/test.properties") public class MyIntegrationTests { // class body... }
@DirtiesContext
@DirtiesContext
indicates that the underlying Spring ApplicationContext
has been dirtied during the execution of a test (that is, the test modified or corrupted it in some manner — for example, by changing the state of a singleton bean) and should be closed. When an application context is marked as dirty, it is removed from the testing framework’s cache and closed. As a consequence, the underlying Spring container is rebuilt for any subsequent test that requires a context with the same configuration metadata.
You can use @DirtiesContext
as both a class-level and a method-level annotation within the same class or class hierarchy. In such scenarios, the ApplicationContext
is marked as dirty before or after any such annotated method as well as before or after the current test class, depending on the configured methodMode
and classMode
. The following examples explain when the context would be dirtied for various configuration scenarios:
- Before the current test class, when declared on a class with class mode set to
BEFORE_CLASS
.
@DirtiesContext(classMode = BEFORE_CLASS) public class FreshContextTests { // some tests that require a new Spring container }
Possible classModes
- BEFORE_CLASS
- AFTER_CLASS
- BEFORE_EACH_TEST_METHOD
- AFTER_EACH_TEST_METHOD
- BEFORE_METHOD
- AFTER_METHOD
@TestExecutionListeners
@TestExecutionListeners
defines class-level metadata for configuring the TestExecutionListener
implementations that should be registered with the TestContextManager
. Typically, @TestExecutionListeners
is used in conjunction with@ContextConfiguration
. The following example shows how to register two TestExecutionListener
implementations:
@ContextConfiguration @TestExecutionListeners({CustomTestExecutionListener.class, AnotherTestExecutionListener.class}) public class CustomTestExecutionListenerTests { // class body... }
@Commit
@Commit
indicates that the transaction for a transactional test method should be committed after the test method has completed. You can use @Commit
as a direct replacement for @Rollback(false)
to more explicitly convey the intent of the code. Analogous to @Rollback
, @Commit
can also be declared as a class-level or method-level annotation. The following example shows how to use the @Commit
annotation:
@Commit @Test public void testProcessWithoutRollback() { // ... }
@Rollback
@Rollback
indicates whether the transaction for a transactional test method should be rolled back after the test method has completed. If true
, the transaction is rolled back. Otherwise, the transaction is committed (see also @Commit
). Rollback for integration tests in the Spring TestContext Framework defaults to true
even if @Rollback
is not explicitly declared.
When declared as a class-level annotation, @Rollback
defines the default rollback semantics for all test methods within the test class hierarchy. When declared as a method-level annotation, @Rollback
defines rollback semantics for the specific test method, potentially overriding class-level @Rollback
or @Commit
semantics. The following example causes a test method’s result to not be rolled back (that is, the result is committed to the database):
@Rollback(false) @Test public void testProcessWithoutRollback() { // ... }
@BeforeTransaction
@BeforeTransaction
indicates that the annotated void
method should run before a transaction is started, for test methods that have been configured to run within a transaction by using Spring’s @Transactional
annotation. The following example shows how to use the @BeforeTransaction
annotation:
@BeforeTransaction void beforeTransaction() { // logic to be executed before a transaction is started }
@AfterTransaction
@AfterTransaction
indicates that the annotated void
method should be run after a transaction is ended, for test methods that have been configured to run within a transaction by using Spring’s @Transactional
annotation.
@Sql
@Sql
is used to annotate a test class or test method to configure SQL scripts to be run against a given database during integration tests. The following example shows how to use it:
@Test @Sql({"/test-schema.sql", "/test-user-data.sql"}) public void userTest { // execute code that relies on the test schema and test data }
@SqlConfig
@SqlConfig
defines metadata that is used to determine how to parse and run SQL scripts configured with the @Sql
annotation. The following example shows how to use it:
@Test @Sql( scripts = "/test-user-data.sql", config = @SqlConfig(commentPrefix = "`", separator = "@@") ) public void userTest { // execute code that relies on the test data }
@SqlGroup
@SqlGroup
is a container annotation that aggregates several @Sql
annotations. You can use @SqlGroup
natively to declare several nested @Sql
annotations, or you can use it in conjunction with Java 8’s support for repeatable annotations, where @Sql
can be declared several times on the same class or method, implicitly generating this container annotation. The following example shows how to declare an SQL group:
@Test @SqlGroup({ @Sql(scripts = "/test-schema.sql", config = @SqlConfig(commentPrefix = "`")), @Sql("/test-user-data.sql") )} public void userTest { // execute code that uses the test schema and test data }
Hope this has given you some understanding of Spring Testing Annotations.