Spring Testing Annotations

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 @Sqlcan 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.

Advertisements