Spring Framework contains the following set of Spring-specific annotations that can be used in your unit and integration tests in conjunction with the TestContext framework. See the corresponding javadoc for more information, including default attribute values, attribute aliases, and more.

The following annotations exist for testing in Spring:

@BootstrapWith

@BootstrapWith is a class-level annotation that can be used to configure how the Spring TestContext Framework bootstraps. In particular, you can use @BootstrapWith to specify a special TestContextBootstrapper. For more information, see Bootstrapping the TestContext framework.

@ContextConfiguration

The @ContextConfiguration annotation defines class-level metadata that is used to determine how to load and configure the ApplicationContext for integration tests. Specifically, @ContextConfiguration declares the locations of application context resources or component classes used to load the context.

Resource locations are typically XML configuration files or Groovy scripts located in the classpath, while component classes are usually classes with the @Configuration annotation. However, resource locations can also reference files and scripts on the file system, and component classes can be classes annotated with @Component, @Service, and so on. For more information, see "Component Classes".

The following example shows the @ContextConfiguration annotation that references an XML file:

Java

@ContextConfiguration("/test-config.xml") 
class XmlApplicationContextTests {
    // class body...
} 
  1. Referring to the XML file.
Kotlin

@ContextConfiguration("/test-config.xml") 
class XmlApplicationContextTests {
    // class body...
} 
  1. Referring to the XML file.

The following example shows @ContextConfiguration annotation that references the class:

Java

@ContextConfiguration(classes = TestConfig.class) 
class ConfigClassApplicationContextTests {
    // class body...
} 
  1. Reference to the class.
Kotlin

@ContextConfiguration(classes = [TestConfig::class]) 
class ConfigClassApplicationContextTests {
    // class body...
} 
  1. Referencing a class.

Alternatively, or in addition to declaring a lookup for resource locations or component classes, you can use @ContextConfiguration to declare the ApplicationContextInitializer classes. The following example shows such a case:

Java

@ContextConfiguration(initializers = CustomContextInitializer.class) 
class ContextInitializerTests {
    // class body...
} 
  1. Declare the class -initializer.
Kotlin

@ContextConfiguration(initializers = [CustomContextInitializer::class]) 
class ContextInitializerTests {
    // class body...
} 
  1. Declare an initializer class.

You can also use the @ContextConfiguration annotation to declare the ContextLoader strategy. Note, however, that it is often not necessary to explicitly configure the loader, since the default loader supports initializers and either locations resources or component classes.

The following example uses both the location and the loader:

Java

@ContextConfiguration(locations = "/test-context.xml", loader = CustomContextLoader.class) 
class CustomLoaderXmlApplicationContextTests {
    // class body...
} 
  1. Configure both the location and the custom bootloader.
Kotlin

@ContextConfiguration("/test-context.xml", loader = CustomContextLoader::class) 
class CustomLoaderXmlApplicationContextTests {
    // class body..
} 
  1. Configure both the location and the custom bootloader.
@ContextConfiguration provides support for inheriting resource locations or configuration classes, as well as context initializers that are declared by superclasses or enclosing classes.

See section dedicated to context management, test class configurations with the annotation @Nested and javadocs with the annotation @ContextConfiguration for more details.

@WebAppConfiguration

@WebAppConfiguration is a class-level annotation that can be used to declare that the ApplicationContext for an integration test should be WebApplicationContext. The very presence of the @WebAppConfiguration annotation in the test class ensures that the test will load the WebApplicationContext using the default value "file:src/main/webapp" for the path to the web application root (that is, the main resource path). The main resource path is used behind the scenes to create a MockServletContext that serves as the ServletContext for the WebApplicationContext test.

The following example shows how to use the annotation @WebAppConfiguration:

Java

@ContextConfiguration
@WebAppConfiguration  
class WebAppTests {
    // class body...
} 
  1. Annotation @WebAppConfiguration.
Kotlin

@ContextConfiguration
@WebAppConfiguration 
class WebAppTests {
    // class body...
} 
  1. Annotation @WebAppConfiguration.

To override the default value, you can set a different primary resource path using an explicit value attribute. Resource prefixes classpath: and file: are supported. If a resource prefix is not specified, the path is assumed to be a file system resource. The following example shows how to set a classpath resource:

Java

@ContextConfiguration
@WebAppConfiguration("classpath:test-web-resources") 
class WebAppTests {
    // class body...
} 
  1. Set a classpath resource.
Kotlin

@ContextConfiguration
@WebAppConfiguration("classpath:test-web-resources") 
class WebAppTests {
    // class body...
} 
  1. Set a classpath resource.

Note that the @WebAppConfiguration annotation must be used either in combination with the @ContextConfiguration within one test class, or within a hierarchy of test classes. For more information, see the javadoc annotation @WebAppConfiguration.

@ContextHierarchy

@ContextHierarchy is a class-level annotation that is used to define a hierarchy of ApplicationContext instances for integration tests. The @ContextHierarchy annotation must be declared using a list of one or more instances of the @ContextConfiguration annotation, each of which defines a level in the context hierarchy. The following examples show the use of the @ContextHierarchy annotation within a single test class (the @ContextHierarchy annotation can also be used within a test class hierarchy):

Java

@ContextHierarchy({
    @ContextConfiguration("/parent-config.xml"),
    @ContextConfiguration("/child-config.xml")
})
class ContextHierarchyTests {
    // class body..
} 
Kotlin

@ContextHierarchy(
    ContextConfiguration("/parent-config.xml"),
    ContextConfiguration( "/child-config.xml"))
class ContextHierarchyTests {
    // class body...
} 
Java

@WebAppConfiguration
@ContextHierarchy({
    @ContextConfiguration(classes = AppConfig.class),
    @ContextConfiguration(classes = WebConfig.class)
})
class WebIntegrationTests {
    // class body...
} 
Kotlin

@WebAppConfiguration
@ContextHierarchy(
        ContextConfiguration(classes = [AppConfig::class]),
        ContextConfiguration(classes = [WebConfig::class]))
class WebIntegrationTests {
    // class body...
} 

If you want to merge or override the configuration for a given level of the context hierarchy in the test class hierarchy, you must explicitly give this level a name by passing the same value to the name attribute in the @ContextConfiguration annotation for each corresponding level of the class hierarchy. For more examples, see "Context Hierarchies" and javadoc by annotation @ContextHierarchy.

@ActiveProfiles

@ActiveProfiles is a class-level annotation that is used to declare which bean definition profiles must be active when loading ApplicationContext for an integration test.

The following example shows that the dev profile must be active:

Java

@ContextConfiguration
@ActiveProfiles("dev") 
class DeveloperTests {
    // class body. ..
} 
  1. Indicate that the dev profile should be active.
Kotlin

@ContextConfiguration
@ActiveProfiles("dev") 
class DeveloperTests {
    // class body...
} 
  1. Indicate that the profile is dev must be active.

The following example shows that both the dev and integration profiles must be active:

Java

@ContextConfiguration
@ActiveProfiles({"dev", "integration"}) 
class DeveloperIntegrationTests {
    // class body...
} 
  1. We indicate that the dev and integration profiles should be active.
Kotlin

@ContextConfiguration
@ActiveProfiles(["dev", "integration"]) 
class DeveloperIntegrationTests {
    // class body...
} 
  1. Indicate that the dev and integration profiles should be active.
The @ActiveProfiles annotation provides support for inheriting active bean definition profiles declared by superclasses and default enclosing classes. You can also programmatically resolve active bean definition profiles by implementing a custom ActiveProfilesResolver and registering it using the resolver attribute of the @ActiveProfiles annotation.

See: sections "Context configuration using environment profiles", "Configuration of a test class with the annotation @Nested", as well as javadoc annotation @ActiveProfiles for examples and more detailed information.

@TestPropertySource

@TestPropertySource – is a class-level annotation that can be used to configure the locations of property files and inline properties to be added to the PropertySources bundle in the Environment for the ApplicationContext, loaded for an integration test.

The following example shows how to declare a properties file from the classpath:

Java

@ContextConfiguration
@TestPropertySource("/test.properties") 
class MyIntegrationTests {
    // class body...
} 
  1. Get properties from test.properties in the root classpath.
Kotlin

@ContextConfiguration
@TestPropertySource("/test.properties") 
class MyIntegrationTests {
    // class body..
} 
  1. Get properties from test.properties at the root of the classpath.

The following example shows how to declare inline properties:

Java

@ContextConfiguration
@TestPropertySource(properties = { "timezone = GMT", "port: 4242" }) 
class MyIntegrationTests {
    // class body...
} 
  1. Declare the properties timezone and port.
Kotlin

@ContextConfiguration
@TestPropertySource(properties = ["timezone = GMT", "port: 4242"]) 
class MyIntegrationTests {
    // class body...
} 
  1. Declare the timezone and port properties.

For examples and more information, see "Context configuration using test property sources".

@DynamicPropertySource

@DynamicPropertySource is a method-level annotation that can be used to register dynamic properties added to the PropertySources bundle in Environment for ApplicationContext loaded for the integration test. Dynamic properties are useful if the property values are not known in advance - for example, if the properties are managed by an external resource, as is the case with a container managed by the project Testcontainers.

The following example shows how to register a dynamic property:

Java

@ContextConfiguration
class MyIntegrationTests {
    static MyExternalServer server = // ...
    @DynamicPropertySource 
    static void dynamicProperties(DynamicPropertyRegistry registry) { 
        registry.add("server.port", server::getPort); 
    }
    // tests ...
} 
  1. Mark the static method with the annotation @DynamicPropertySource.
  2. Accept DynamicPropertyRegistry as an argument .
  3. Register the dynamic property server.port, which will be received from the server later.
Kotlin

@ContextConfiguration
class MyIntegrationTests {
    companion object {
        @JvmStatic
        val server: MyExternalServer = // ...
        @DynamicPropertySource
        @JvmStatic
        fun dynamicProperties(registry: DynamicPropertyRegistry) { 
            registry.add("server.port", server::getPort)
        }
    }
    // tests ...
} 
  1. Mark the static method with the annotation @DynamicPropertySource .
  2. We accept DynamicPropertyRegistry as an argument.
  3. We register the dynamic property server.port, which will be received from the server deferred.< /li>

For more information, see "Context configuration using dynamic property sources".

@DirtiesContext

The @DirtiesContext annotation indicates that the underlying ApplicationContext is from Spring was "contaminated" during test execution (that is, the test changed or corrupted it in some way - for example, changing the state of a singleton bean) and needs to be closed. If an application context is marked as dirty, it is removed from the testing system cache and closed. As a result, the base Spring container is rebuilt for any subsequent test that necessarily requires a context with the same configuration metadata.

The @DirtiesContext annotation can be used both at the class level and at the method level within a single class or class hierarchy. In such scenarios, the ApplicationContext is marked as dirty before or after any such annotated method, and before or after the current test class, depending on the configured methodMode and classMode .

The following examples explain when the context can be "polluted" under various configuration scenarios:

  • Before the current test class, if declared for a class using the class mode set to BEFORE_CLASS.

    Java
    
    @DirtiesContext(classMode = BEFORE_CLASS) 
    class FreshContextTests {
        // some tests that require a new Spring container
    }
    1. "Dirty" context before the current test class.
    Kotlin
    
    @DirtiesContext(classMode = BEFORE_CLASS ) 
    class FreshContextTests {
        // some tests that require a new Spring container
    } 
    1. The "dirty" context is before the current test class.
  • After the current test class, if declared for a class whose class mode is set to AFTER_CLASS (i.e. default class mode).

    Java
    
    @DirtiesContext 
    class ContextDirtyingTests {
        // some tests that pollute the Spring container
    } 
    1. "Dirty" context after the current one test class.
    Kotlin
    
    @DirtiesContext 
    class ContextDirtyingTests {
        // some tests that cause the Spring container to become dirty
    } 
    1. "Dirty" context after the current test class.
  • Before each test method in the current test class, if declared for a class whose class mode is set to BEFORE_EACH_TEST_METHOD.

    Java
    
    @DirtiesContext(classMode = BEFORE_EACH_TEST_METHOD) 
    class FreshContextTests {
        // some tests that require a new Spring container
    } 
    1. Dirty context before each test method.
    Kotlin
    
    @DirtiesContext(classMode = BEFORE_EACH_TEST_METHOD) 
    class FreshContextTests {
        // some tests that require a new Spring container
    } 
    1. " Dirty" context before each test method.
  • After each test method in the current test class, if declared for a class whose class mode is set to AFTER_EACH_TEST_METHOD.

    Java
    
    @DirtiesContext(classMode = AFTER_EACH_TEST_METHOD) 
    class ContextDirtyingTests {
        // some tests that cause the Spring container to become dirty
    } 
    1. "Dirty" context after each test method.
    Kotlin
    
    @DirtiesContext(classMode = AFTER_EACH_TEST_METHOD) 
    class ContextDirtyingTests {
        // some tests that lead to Spring container contamination
    } 
    1. Dirty context after each test method.
  • Before the current test, if declared for a method whose method mode is set to BEFORE_METHOD.

    Java
    
    @DirtiesContext(methodMode = BEFORE_METHOD) 
    @Test
    void testProcessWhichRequiresFreshAppCtx() {
        // some logic that requires a new Spring container
    } 
    1. "Dirty" context before the current test method.
    Kotlin
    
    @DirtiesContext(methodMode = BEFORE_METHOD) 
    @Test
    fun testProcessWhichRequiresFreshAppCtx() {
        // some logic that requires a new Spring container
    } 
    1. "Dirty" context before the current test method.
  • After the current test, if declared in a method whose method mode is set to AFTER_METHOD (i.e. default method mode).

    Java
    
    @DirtiesContext 
    @Test
    void testProcessWhichDirtiesAppCtx() {
        // some logic that causes the Spring container to become dirty
    } 
    1. "Dirty " context after the current test method.
    Kotlin
    
    @DirtiesContext 
    @Test
    fun testProcessWhichDirtiesAppCtx() {
        // some logic that pollutes the Spring container
    } 
    1. The "dirty" context after the current test method.

If you use the @DirtiesContext annotation in a test whose context is configured as part of a context hierarchy using the @ContextHierarchy annotation, the hierarchyMode flag can be used to control the process of clearing the context cache. By default, to clear the context cache, an exhaustive search algorithm is used, affecting not only the current level, but also all other context hierarchies that have a common ancestor context with the current test. All instances of ApplicationContext that are in the common ancestor context hierarchy branch are removed from the context cache and closed. If the exhaustive search algorithm is overkill for a particular use case, then you can specify a simpler current-level algorithm, as shown in the following example.

Java

@ContextHierarchy({
    @ContextConfiguration("/parent-config.xml"),
    @ContextConfiguration("/child-config.xml")
})
class BaseTests {
    // class body...
}
class ExtendedTests extends BaseTests {
    @Test
    @DirtiesContext(hierarchyMode = CURRENT_LEVEL) 
    void test() {
        // some logic that pollutes the child context
    }
} 
  1. We use the current level algorithm.
Kotlin

@ContextHierarchy(
    ContextConfiguration("/parent-config.xml"),
    ContextConfiguration("/child-config.xml"))
open class BaseTests {
    // class body...
}
class ExtendedTests : BaseTests() {
    @Test
    @DirtiesContext (hierarchyMode = CURRENT_LEVEL) 
    fun test() {
        // some logic that pollutes the child context
    }
} 
  1. We use the current level algorithm.

More information about the algorithms EXHAUSTIVE and CURRENT_LEVEL see javadoc at "DirtiesContext.HierarchyMode".

@TestExecutionListeners

@TestExecutionListeners is used to register listeners for a specific test class, its subclasses and nested classes. If you need to register a listener globally, you should register it through the automatic discovery mechanism described in the Configuration section TestExecutionListener.

The following example shows how to register two implementations of TestExecutionListener:

Java

@ContextConfiguration
@TestExecutionListeners({CustomTestExecutionListener.class, AnotherTestExecutionListener.class}) 
class CustomTestExecutionListenerTests {
    // class body...
} 
  1. Register two implementations of TestExecutionListener.
Kotlin

@ContextConfiguration
@TestExecutionListeners(CustomTestExecutionListener::class, AnotherTestExecutionListener::class) 
class CustomTestExecutionListenerTests {
    // class body...
} 
  1. Register two implementations TestExecutionListener.

By default, the @TestExecutionListeners annotation provides support for inheriting listeners from superclasses or enclosing classes. See "Test class configuration with @Nested annotation" and javadoc by annotation @TestExecutionListeners for an example and detailed information. If you find that you need to revert to using standard TestExecutionListener implementations, please see the note in "Registering implementations of TestExecutionListener".

@RecordApplicationEvents

Annotation @RecordApplicationEvents is an annotation on class level, which is used to instruct the Spring TestContext Framework to record all application events that are published to the ApplicationContext during the execution of a single test.

Recorded events can be accessed through the ApplicationEvents API within tests.

See: javadoc on "Application Events" and "@RecordApplicationEvents Annotations" for an example and obtain further details.

@Commit

The @Commit annotation specifies that the transaction for a transactional test method should be committed after the test method completes. You can use the @Commit annotation as a direct replacement for the @Rollback(false) annotation to make the code more explicit. Similar to the @Rollback annotation, the @Commit annotation can also be declared as a class- or method-level annotation.

The following example shows how to use the annotation @Commit:

Java

@Commit 
@Test
void testProcessWithoutRollback() {
    // ...
} 
  1. Fix the test result in the database .
Kotlin

@Commit 
@Test
fun testProcessWithoutRollback() {
    // ...
} 
  1. Fix the test result in the database.
@Rollback

The @Rollback annotation specifies whether the transaction for a transactional test method should be rolled back after the test method completes. If set to 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 the @Rollback annotation is not explicitly declared.

If the annotation is @Rollback is declared as a class-level annotation, then it defines the default rollback semantics for all test methods in the test class hierarchy. If the @Rollback annotation is declared at the method level, it defines the rollback semantics for a particular test method, potentially overriding the semantics of the @Rollback or @Commit annotation at the level class.

In the following example, the result of the test method is not rolled back (that is, the result is committed to the database):

Java

@Rollback(false ) 
@Test
void testProcessWithoutRollback() {
    // ...
} 
  1. We do not roll back the result.
Kotlin

@Rollback(false) 
@Test
fun testProcessWithoutRollback() {
    // ...
} 
  1. We do not roll back the result.
@BeforeTransaction

The @BeforeTransaction annotation indicates that the annotated void the method should be executed before the transaction begins in the case of test methods configured to execute within a transaction via the @Transactional annotation from Spring. Methods marked with the @BeforeTransaction annotation are optional must be public, and they can be declared in interface methods with the default implementation based on Java 8.

The following example shows how to use the annotation @BeforeTransaction :

Java

@BeforeTransaction 
void beforeTransaction() {
    // logic that should be executed before the transaction begins
} 
  1. Run this method before the transaction.
Kotlin

@BeforeTransaction 
fun beforeTransaction() {
    // logic that should be executed before the transaction begins
} 
  1. Run this method before the transaction.
@AfterTransaction

The @AfterTransaction annotation specifies that the void annotated method should be executed after the transaction completes in the case of test methods configured to execute within a transaction via the @Transactional annotation from Spring. Methods marked with the @AfterTransaction annotation do not need to be public, and they can be declared in interface methods with the default Java 8-based implementation.

Java

@AfterTransaction 
void afterTransaction() {
    // logic that will be executed after the transaction is completed
}
  1. We execute this method after the transaction.
Kotlin

AfterTransaction 
fun afterTransaction() {
    // logic that will be executed after the transaction is completed
}
  1. We execute this method after the transaction.
@Sql

The @Sql annotation is used to annotate a test class or test method to configure the SQL scripts that will be executed against a given database during integration tests. The following example shows how to use it:

Java

@Test
@Sql({"/test-schema.sql", "/test-user-data.sql"}) 
void userTest() {
    // execute code that uses test circuit and test data
}
  1. Run two scripts for this test.
Kotlin

@Test
@Sql("/test-schema.sql", "/test-user-data.sql") 
fun userTest() {
    // execute code that uses test circuit and test data
}
  1. Run two scripts for this test.

For more information, see "Declaratively executing SQL scripts using @Sql annotations.

@SqlConfig

The @SqlConfig annotation 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:

Java

@Test
@Sql(
    scripts = "/test-user-data.sql",
    config = @SqlConfig(commentPrefix = "`", separator = "@@") 
)
void userTest() {
    // execute code that uses test data
}
  1. Set the comment prefix and delimiter in SQL scripts.
Kotlin

@Test
@Sql("/test-user-data.sql", config = SqlConfig(commentPrefix = "`", separator = "@@")) 
fun userTest() {
    // execute code that uses test data
}
  1. Set the comment prefix and delimiter in SQL scripts.
@SqlMergeMode

The @SqlMergeMode annotation is used to annotate a test class or test method to configure the method level @Sql annotation declarations to be merged with the @Sql annotation declarations at the class level. If the @SqlMergeMode annotation has not been declared for a test class or test method, then the default merge mode OVERRIDE will be used. In OVERRIDE mode, @Sql annotation declarations at the method level will effectively override @Sql annotation declarations at the class level.

Note that declaring the @SqlMergeMode annotation at the method level overrides the declaration at the class level.

The following example shows how to use the annotation @SqlMergeMode at the class level.

Java
@SpringJUnitConfig(TestConfig.class)
@Sql("/test-schema.sql")
@SqlMergeMode(MERGE) 
class UserTests {
    @Test
    @Sql("/user-test-data-001.sql")
    void standardUserProfile() {
        // execute code that uses test data set 001
    }
}
  1. Set the @Sql annotation merging mode to MERGE for all test methods in the class.
Kotlin
@SpringJUnitConfig(TestConfig::class)
@Sql("/test-schema.sql")
@SqlMergeMode(MERGE) 
class UserTests {
    @Test
    @Sql("/user-test-data-001.sql")
    fun standardUserProfile() {
        // execute code that uses test data set 001
    }
}
  1. Set the @Sql annotation merging mode to MERGE for all test methods in the class.

The following example shows how to use the annotation @SqlMergeMode at the method level.

Java
@SpringJUnitConfig(TestConfig.class)
@Sql("/test-schema.sql")
class UserTests {
    @Test
    @Sql("/user-test-data-001.sql")
    @SqlMergeMode(MERGE) 
    void standardUserProfile() {
        // execute code that uses test data set 001
    }
}
  1. Set the @Sql annotation merging mode to MERGE for a specific test method.
Kotlin
@SpringJUnitConfig(TestConfig::class)
@Sql("/test-schema.sql")
class UserTests {
    @Test
    @Sql("/user-test-data-001.sql")
    @SqlMergeMode(MERGE) 
    fun standardUserProfile() {
        // execute code that uses test data set 001
    }
}
  1. Set the @Sql annotation merging mode to MERGE for a specific test method.
@SqlGroup

@SqlGroup is a container annotation that combines multiple @Sql annotations. You can use the @SqlGroup annotation to declare multiple nested @Sql annotations, or use it in combination with the Java 8 duplicate annotation support where the @Sql annotation can be declared multiple times for the same class or method, implicitly generating this container annotation. The following example shows how to declare an SQL group:

Java
@Test
@SqlGroup({ 
    @Sql(scripts = "/test-schema.sql", config = @SqlConfig(commentPrefix = "`")),
    @Sql("/test-user-data.sql")
})
void userTest() {
    // execute code using test circuit and test data
}
  1. Declare a group of SQL scripts.
Kotlin
@Test
@SqlGroup( 
    Sql("/test-schema.sql", config = SqlConfig(commentPrefix = "`")),
    Sql("/test-user-data.sql"))
fun userTest() {
    // execute code using test circuit and test data
}
  1. Declare a group of SQL scripts.