Spring Boot provides a number of utilities and annotations to help when testing your application.
Test support is provided by two modules: spring-boot-test
contains core items, and spring-boot-test-autoconfigure
supports auto-configuration for tests.
Most developers use the spring-boot-starter-test
“Starter”, which imports both Spring Boot test modules as well as JUnit Jupiter, AssertJ, Hamcrest, and a number of other useful libraries.
Tip
|
If you have tests that use JUnit 4, JUnit 5’s vintage engine can be used to run them.
To use the vintage engine, add a dependency on <dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency> |
hamcrest-core
is excluded in favor of org.hamcrest:hamcrest
that is part of spring-boot-starter-test
.
The spring-boot-starter-test
“Starter” (in the test
scope
) contains the following provided libraries:
-
JUnit 5: The de-facto standard for unit testing Java applications.
-
{spring-framework-docs}/testing/integration.html[Spring Test] & Spring Boot Test: Utilities and integration test support for Spring Boot applications.
-
AssertJ: A fluent assertion library.
-
Hamcrest: A library of matcher objects (also known as constraints or predicates).
-
Mockito: A Java mocking framework.
-
JSONassert: An assertion library for JSON.
-
JsonPath: XPath for JSON.
-
Awaitility: A library for testing asynchronous systems.
We generally find these common libraries to be useful when writing tests. If these libraries do not suit your needs, you can add additional test dependencies of your own.
One of the major advantages of dependency injection is that it should make your code easier to unit test.
You can instantiate objects by using the new
operator without even involving Spring.
You can also use mock objects instead of real dependencies.
Often, you need to move beyond unit testing and start integration testing (with a Spring ApplicationContext
).
It is useful to be able to perform integration testing without requiring deployment of your application or needing to connect to other infrastructure.
The Spring Framework includes a dedicated test module for such integration testing.
You can declare a dependency directly to org.springframework:spring-test
or use the spring-boot-starter-test
“Starter” to pull it in transitively.
If you have not used the spring-test
module before, you should start by reading the {spring-framework-docs}/testing.html[relevant section] of the Spring Framework reference documentation.
A Spring Boot application is a Spring ApplicationContext
, so nothing very special has to be done to test it beyond what you would normally do with a vanilla Spring context.
Note
|
External properties, logging, and other features of Spring Boot are installed in the context by default only if you use SpringApplication to create it.
|
Spring Boot provides a @SpringBootTest
annotation, which can be used as an alternative to the standard spring-test
@ContextConfiguration
annotation when you need Spring Boot features.
The annotation works by creating the ApplicationContext
used in your tests through SpringApplication
.
In addition to @SpringBootTest
a number of other annotations are also provided for testing more specific slices of an application.
Tip
|
If you are using JUnit 4, do not forget to also add @RunWith(SpringRunner.class) to your test, otherwise the annotations will be ignored.
If you are using JUnit 5, there is no need to add the equivalent @ExtendWith(SpringExtension.class) as @SpringBootTest and the other @…Test annotations are already annotated with it.
|
By default, @SpringBootTest
will not start a server.
You can use the webEnvironment
attribute of @SpringBootTest
to further refine how your tests run:
-
MOCK
(Default) : Loads a webApplicationContext
and provides a mock web environment. Embedded servers are not started when using this annotation. If a web environment is not available on your classpath, this mode transparently falls back to creating a regular non-webApplicationContext
. It can be used in conjunction with@AutoConfigureMockMvc
or@AutoConfigureWebTestClient
for mock-based testing of your web application. -
RANDOM_PORT
: Loads aWebServerApplicationContext
and provides a real web environment. Embedded servers are started and listen on a random port. -
DEFINED_PORT
: Loads aWebServerApplicationContext
and provides a real web environment. Embedded servers are started and listen on a defined port (from yourapplication.properties
) or on the default port of8080
. -
NONE
: Loads anApplicationContext
by usingSpringApplication
but does not provide any web environment (mock or otherwise).
Note
|
If your test is @Transactional , it rolls back the transaction at the end of each test method by default.
However, as using this arrangement with either RANDOM_PORT or DEFINED_PORT implicitly provides a real servlet environment, the HTTP client and server run in separate threads and, thus, in separate transactions.
Any transaction initiated on the server does not roll back in this case.
|
Note
|
@SpringBootTest with webEnvironment = WebEnvironment.RANDOM_PORT will also start the management server on a separate random port if your application uses a different port for the management server.
|
If Spring MVC is available, a regular MVC-based application context is configured. If you have only Spring WebFlux, we will detect that and configure a WebFlux-based application context instead.
If both are present, Spring MVC takes precedence. If you want to test a reactive web application in this scenario, you must set the configprop:spring.main.web-application-type[] property:
code:MyWebFluxTests
If you are familiar with the Spring Test Framework, you may be used to using @ContextConfiguration(classes=…)
in order to specify which Spring @Configuration
to load.
Alternatively, you might have often used nested @Configuration
classes within your test.
When testing Spring Boot applications, this is often not required.
Spring Boot’s @*Test
annotations search for your primary configuration automatically whenever you do not explicitly define one.
The search algorithm works up from the package that contains the test until it finds a class annotated with @SpringBootApplication
or @SpringBootConfiguration
.
As long as you structured your code in a sensible way, your main configuration is usually found.
Note
|
If you use a test annotation to test a more specific slice of your application, you should avoid adding configuration settings that are specific to a particular area on the main method’s application class. The underlying component scan configuration of |
If you want to customize the primary configuration, you can use a nested @TestConfiguration
class.
Unlike a nested @Configuration
class, which would be used instead of your application’s primary configuration, a nested @TestConfiguration
class is used in addition to your application’s primary configuration.
Note
|
Spring’s test framework caches application contexts between tests. Therefore, as long as your tests share the same configuration (no matter how it is discovered), the potentially time-consuming process of loading the context happens only once. |
Typically the test configuration discovered by @SpringBootTest
will be your main @SpringBootApplication
.
In most well structured applications, this configuration class will also include the main
method used to launch the application.
For example, the following is a very common code pattern for a typical Spring Boot application:
code:typical/MyApplication
In the example above, the main
method doesn’t do anything other than delegate to SpringApplication.run
.
It is, however, possible to have a more complex main
method that applies customizations before calling SpringApplication.run
.
For example, here is an application that changes the banner mode and sets additional profiles:
code:custom/MyApplication
Since customizations in the main
method can affect the resulting ApplicationContext
, it’s possible that you might also want to use the main
method to create the ApplicationContext
used in your tests.
By default, @SpringBootTest
will not call your main
method, and instead the class itself is used directly to create the ApplicationContext
If you want to change this behavior, you can change the useMainMethod
attribute of @SpringBootTest
to UseMainMethod.ALWAYS
or UseMainMethod.WHEN_AVAILABLE
.
When set to ALWAYS
, the test will fail if no main
method can be found.
When set to WHEN_AVAILABLE
the main
method will be used if it is available, otherwise the standard loading mechanism will be used.
For example, the following test will invoke the main
method of MyApplication
in order to create the ApplicationContext
.
If the main method sets additional profiles then those will be active when the ApplicationContext
starts.
code:always/MyApplicationTests
If your application uses component scanning (for example, if you use @SpringBootApplication
or @ComponentScan
), you may find top-level configuration classes that you created only for specific tests accidentally get picked up everywhere.
As we have seen earlier, @TestConfiguration
can be used on an inner class of a test to customize the primary configuration.
@TestConfiguration
can also be used on a top-level class. Doing so indicates that the class should not be picked up by scanning.
You can then import the class explicitly where it is required, as shown in the following example:
code:MyTests
Note
|
If you directly use @ComponentScan (that is, not through @SpringBootApplication ) you need to register the TypeExcludeFilter with it.
See {spring-boot-module-api}/context/TypeExcludeFilter.html[the Javadoc] for details.
|
Note
|
An imported @TestConfiguration is processed earlier than an inner-class @TestConfiguration and an imported @TestConfiguration will be processed before any configuration found through component scanning.
Generally speaking, this difference in ordering has no noticeable effect but it is something to be aware of if you’re relying on bean overriding.
|
If your application expects arguments, you can
have @SpringBootTest
inject them using the args
attribute.
code:MyApplicationArgumentTests
By default, @SpringBootTest
does not start the server but instead sets up a mock environment for testing web endpoints.
With Spring MVC, we can query our web endpoints using {spring-framework-docs}/testing/spring-mvc-test-framework.html[MockMvc
] or WebTestClient
, as shown in the following example:
code:MyMockMvcTests
Tip
|
If you want to focus only on the web layer and not start a complete ApplicationContext , consider using @WebMvcTest instead.
|
With Spring WebFlux endpoints, you can use {spring-framework-docs}/testing/webtestclient.html[WebTestClient
] as shown in the following example:
code:MyMockWebTestClientTests
Tip
|
Testing within a mocked environment is usually faster than running with a full servlet container. However, since mocking occurs at the Spring MVC layer, code that relies on lower-level servlet container behavior cannot be directly tested with MockMvc. For example, Spring Boot’s error handling is based on the “error page” support provided by the servlet container. This means that, whilst you can test your MVC layer throws and handles exceptions as expected, you cannot directly test that a specific custom error page is rendered. If you need to test these lower-level concerns, you can start a fully running server as described in the next section. |
If you need to start a full running server, we recommend that you use random ports.
If you use @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
, an available port is picked at random each time your test runs.
The @LocalServerPort
annotation can be used to inject the actual port used into your test.
For convenience, tests that need to make REST calls to the started server can additionally @Autowire
a {spring-framework-docs}/testing/webtestclient.html[WebTestClient
], which resolves relative links to the running server and comes with a dedicated API for verifying responses, as shown in the following example:
code:MyRandomPortWebTestClientTests
Tip
|
WebTestClient can also used with a mock environment, removing the need for a running server, by annotating your test class with @AutoConfigureWebTestClient .
|
This setup requires spring-webflux
on the classpath.
If you can not or will not add webflux, Spring Boot also provides a TestRestTemplate
facility:
code:MyRandomPortTestRestTemplateTests
To customize the WebTestClient
bean, configure a WebTestClientBuilderCustomizer
bean.
Any such beans are called with the WebTestClient.Builder
that is used to create the WebTestClient
.
As the test context framework caches context, JMX is disabled by default to prevent identical components to register on the same domain.
If such test needs access to an MBeanServer
, consider marking it dirty as well:
code:MyJmxTests
Regardless of your classpath, meter registries, except the in-memory backed, are not auto-configured when using @SpringBootTest
.
If you need to export metrics to a different backend as part of an integration test, annotate it with @AutoConfigureObservability
.
Regardless of your classpath, tracing components which are reporting data are not auto-configured when using @SpringBootTest
.
If you need those components as part of an integration test, annotate the test with @AutoConfigureObservability
.
If you have created your own reporting components (e.g. a custom SpanExporter
or SpanHandler
) and you don’t want them to be active in tests, you can use the @ConditionalOnEnabledTracing
annotation to disable them.
When running tests, it is sometimes necessary to mock certain components within your application context. For example, you may have a facade over some remote service that is unavailable during development. Mocking can also be useful when you want to simulate failures that might be hard to trigger in a real environment.
Spring Boot includes a @MockBean
annotation that can be used to define a Mockito mock for a bean inside your ApplicationContext
.
You can use the annotation to add new beans or replace a single existing bean definition.
The annotation can be used directly on test classes, on fields within your test, or on @Configuration
classes and fields.
When used on a field, the instance of the created mock is also injected.
Mock beans are automatically reset after each test method.
Note
|
If your test uses one of Spring Boot’s test annotations (such as code:listener/MyTests |
The following example replaces an existing RemoteService
bean with a mock implementation:
code:bean/MyTests
Note
|
@MockBean cannot be used to mock the behavior of a bean that is exercised during application context refresh.
By the time the test is executed, the application context refresh has completed and it is too late to configure the mocked behavior.
We recommend using a @Bean method to create and configure the mock in this situation.
|
Additionally, you can use @SpyBean
to wrap any existing bean with a Mockito spy
.
See the {spring-boot-test-module-api}/mock/mockito/SpyBean.html[Javadoc] for full details.
Note
|
While Spring’s test framework caches application contexts between tests and reuses a context for tests sharing the same configuration, the use of @MockBean or @SpyBean influences the cache key, which will most likely increase the number of contexts.
|
Tip
|
If you are using @SpyBean to spy on a bean with @Cacheable methods that refer to parameters by name, your application must be compiled with -parameters .
This ensures that the parameter names are available to the caching infrastructure once the bean has been spied upon.
|
Tip
|
When you are using @SpyBean to spy on a bean that is proxied by Spring, you may need to remove Spring’s proxy in some situations, for example when setting expectations using given or when .
Use AopTestUtils.getTargetObject(yourProxiedSpy) to do so.
|
Spring Boot’s auto-configuration system works well for applications but can sometimes be a little too much for tests. It often helps to load only the parts of the configuration that are required to test a “slice” of your application. For example, you might want to test that Spring MVC controllers are mapping URLs correctly, and you do not want to involve database calls in those tests, or you might want to test JPA entities, and you are not interested in the web layer when those tests run.
The spring-boot-test-autoconfigure
module includes a number of annotations that can be used to automatically configure such “slices”.
Each of them works in a similar way, providing a @…Test
annotation that loads the ApplicationContext
and one or more @AutoConfigure…
annotations that can be used to customize auto-configuration settings.
Note
|
Each slice restricts component scan to appropriate components and loads a very restricted set of auto-configuration classes.
If you need to exclude one of them, most @…Test annotations provide an excludeAutoConfiguration attribute.
Alternatively, you can use @ImportAutoConfiguration#exclude .
|
Note
|
Including multiple “slices” by using several @…Test annotations in one test is not supported.
If you need multiple “slices”, pick one of the @…Test annotations and include the @AutoConfigure… annotations of the other “slices” by hand.
|
Tip
|
It is also possible to use the @AutoConfigure… annotations with the standard @SpringBootTest annotation.
You can use this combination if you are not interested in “slicing” your application but you want some of the auto-configured test beans.
|
To test that object JSON serialization and deserialization is working as expected, you can use the @JsonTest
annotation.
@JsonTest
auto-configures the available supported JSON mapper, which can be one of the following libraries:
-
Jackson
ObjectMapper
, any@JsonComponent
beans and any JacksonModule
s -
Gson
-
Jsonb
Tip
|
A list of the auto-configurations that are enabled by @JsonTest can be found in the appendix.
|
If you need to configure elements of the auto-configuration, you can use the @AutoConfigureJsonTesters
annotation.
Spring Boot includes AssertJ-based helpers that work with the JSONAssert and JsonPath libraries to check that JSON appears as expected.
The JacksonTester
, GsonTester
, JsonbTester
, and BasicJsonTester
classes can be used for Jackson, Gson, Jsonb, and Strings respectively.
Any helper fields on the test class can be @Autowired
when using @JsonTest
.
The following example shows a test class for Jackson:
code:MyJsonTests
Note
|
JSON helper classes can also be used directly in standard unit tests.
To do so, call the initFields method of the helper in your @Before method if you do not use @JsonTest .
|
If you use Spring Boot’s AssertJ-based helpers to assert on a number value at a given JSON path, you might not be able to use isEqualTo
depending on the type.
Instead, you can use AssertJ’s satisfies
to assert that the value matches the given condition.
For instance, the following example asserts that the actual number is a float value close to 0.15
within an offset of 0.01
.
code:MyJsonAssertJTests
To test whether Spring MVC controllers are working as expected, use the @WebMvcTest
annotation.
@WebMvcTest
auto-configures the Spring MVC infrastructure and limits scanned beans to @Controller
, @ControllerAdvice
, @JsonComponent
, Converter
, GenericConverter
, Filter
, HandlerInterceptor
, WebMvcConfigurer
, WebMvcRegistrations
, and HandlerMethodArgumentResolver
.
Regular @Component
and @ConfigurationProperties
beans are not scanned when the @WebMvcTest
annotation is used.
@EnableConfigurationProperties
can be used to include @ConfigurationProperties
beans.
Tip
|
A list of the auto-configuration settings that are enabled by @WebMvcTest can be found in the appendix.
|
Tip
|
If you need to register extra components, such as the Jackson Module , you can import additional configuration classes by using @Import on your test.
|
Often, @WebMvcTest
is limited to a single controller and is used in combination with @MockBean
to provide mock implementations for required collaborators.
@WebMvcTest
also auto-configures MockMvc
.
Mock MVC offers a powerful way to quickly test MVC controllers without needing to start a full HTTP server.
Tip
|
You can also auto-configure MockMvc in a non-@WebMvcTest (such as @SpringBootTest ) by annotating it with @AutoConfigureMockMvc .
The following example uses MockMvc :
|
code:MyControllerTests
Tip
|
If you need to configure elements of the auto-configuration (for example, when servlet filters should be applied) you can use attributes in the @AutoConfigureMockMvc annotation.
|
If you use HtmlUnit and Selenium, auto-configuration also provides an HtmlUnit WebClient
bean and/or a Selenium WebDriver
bean.
The following example uses HtmlUnit:
code:MyHtmlUnitTests
Note
|
By default, Spring Boot puts WebDriver beans in a special “scope” to ensure that the driver exits after each test and that a new instance is injected.
If you do not want this behavior, you can add @Scope("singleton") to your WebDriver @Bean definition.
|
Warning
|
The webDriver scope created by Spring Boot will replace any user defined scope of the same name.
If you define your own webDriver scope you may find it stops working when you use @WebMvcTest .
|
If you have Spring Security on the classpath, @WebMvcTest
will also scan WebSecurityConfigurer
beans.
Instead of disabling security completely for such tests, you can use Spring Security’s test support.
More details on how to use Spring Security’s MockMvc
support can be found in this howto.adoc how-to section.
Tip
|
Sometimes writing Spring MVC tests is not enough; Spring Boot can help you run full end-to-end tests with an actual server. |
To test that {spring-framework-docs}/web-reactive.html[Spring WebFlux] controllers are working as expected, you can use the @WebFluxTest
annotation.
@WebFluxTest
auto-configures the Spring WebFlux infrastructure and limits scanned beans to @Controller
, @ControllerAdvice
, @JsonComponent
, Converter
, GenericConverter
, WebFilter
, and WebFluxConfigurer
.
Regular @Component
and @ConfigurationProperties
beans are not scanned when the @WebFluxTest
annotation is used.
@EnableConfigurationProperties
can be used to include @ConfigurationProperties
beans.
Tip
|
A list of the auto-configurations that are enabled by @WebFluxTest can be found in the appendix.
|
Tip
|
If you need to register extra components, such as Jackson Module , you can import additional configuration classes using @Import on your test.
|
Often, @WebFluxTest
is limited to a single controller and used in combination with the @MockBean
annotation to provide mock implementations for required collaborators.
@WebFluxTest
also auto-configures {spring-framework-docs}/testing/webtestclient.html[WebTestClient
], which offers a powerful way to quickly test WebFlux controllers without needing to start a full HTTP server.
Tip
|
You can also auto-configure WebTestClient in a non-@WebFluxTest (such as @SpringBootTest ) by annotating it with @AutoConfigureWebTestClient .
The following example shows a class that uses both @WebFluxTest and a WebTestClient :
|
code:MyControllerTests
Tip
|
This setup is only supported by WebFlux applications as using WebTestClient in a mocked web application only works with WebFlux at the moment.
|
Note
|
@WebFluxTest cannot detect routes registered through the functional web framework.
For testing RouterFunction beans in the context, consider importing your RouterFunction yourself by using @Import or by using @SpringBootTest .
|
Note
|
@WebFluxTest cannot detect custom security configuration registered as a @Bean of type SecurityWebFilterChain .
To include that in your test, you will need to import the configuration that registers the bean by using @Import or by using @SpringBootTest .
|
Tip
|
Sometimes writing Spring WebFlux tests is not enough; Spring Boot can help you run full end-to-end tests with an actual server. |
Spring GraphQL offers a dedicated testing support module; you’ll need to add it to your project:
<dependencies>
<dependency>
<groupId>org.springframework.graphql</groupId>
<artifactId>spring-graphql-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Unless already present in the compile scope -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
dependencies {
testImplementation("org.springframework.graphql:spring-graphql-test")
// Unless already present in the implementation configuration
testImplementation("org.springframework.boot:spring-boot-starter-webflux")
}
This testing module ships the {spring-graphql-docs}/#testing-graphqltester[GraphQlTester].
The tester is heavily used in test, so be sure to become familiar with using it.
There are GraphQlTester
variants and Spring Boot will auto-configure them depending on the type of tests:
-
the
ExecutionGraphQlServiceTester
performs tests on the server side, without a client nor a transport -
the
HttpGraphQlTester
performs tests with a client that connects to a server, with or without a live server
Spring Boot helps you to test your {spring-graphql-docs}/#controllers[Spring GraphQL Controllers] with the @GraphQlTest
annotation.
@GraphQlTest
auto-configures the Spring GraphQL infrastructure, without any transport nor server being involved.
This limits scanned beans to @Controller
, RuntimeWiringConfigurer
, JsonComponent
, Converter
, GenericConverter
, DataFetcherExceptionResolver
, Instrumentation
and GraphQlSourceBuilderCustomizer
.
Regular @Component
and @ConfigurationProperties
beans are not scanned when the @GraphQlTest
annotation is used.
@EnableConfigurationProperties
can be used to include @ConfigurationProperties
beans.
Tip
|
A list of the auto-configurations that are enabled by @GraphQlTest can be found in the appendix.
|
Often, @GraphQlTest
is limited to a set of controllers and used in combination with the @MockBean
annotation to provide mock implementations for required collaborators.
code:GreetingControllerTests
@SpringBootTest
tests are full integration tests and involve the entire application.
When using a random or defined port, a live server is configured and an HttpGraphQlTester
bean is contributed automatically so you can use it to test your server.
When a MOCK environment is configured, you can also request an HttpGraphQlTester
bean by annotating your test class with @AutoConfigureHttpGraphQlTester
:
code:GraphQlIntegrationTests
You can use @DataCassandraTest
to test Cassandra applications.
By default, it configures a CassandraTemplate
, scans for @Table
classes, and configures Spring Data Cassandra repositories.
Regular @Component
and @ConfigurationProperties
beans are not scanned when the @DataCassandraTest
annotation is used.
@EnableConfigurationProperties
can be used to include @ConfigurationProperties
beans.
(For more about using Cassandra with Spring Boot, see "data.adoc".)
Tip
|
A list of the auto-configuration settings that are enabled by @DataCassandraTest can be found in the appendix.
|
The following example shows a typical setup for using Cassandra tests in Spring Boot:
code:MyDataCassandraTests
You can use @DataCouchbaseTest
to test Couchbase applications.
By default, it configures a CouchbaseTemplate
or ReactiveCouchbaseTemplate
, scans for @Document
classes, and configures Spring Data Couchbase repositories.
Regular @Component
and @ConfigurationProperties
beans are not scanned when the @DataCouchbaseTest
annotation is used.
@EnableConfigurationProperties
can be used to include @ConfigurationProperties
beans.
(For more about using Couchbase with Spring Boot, see "data.adoc", earlier in this chapter.)
Tip
|
A list of the auto-configuration settings that are enabled by @DataCouchbaseTest can be found in the appendix.
|
The following example shows a typical setup for using Couchbase tests in Spring Boot:
code:MyDataCouchbaseTests
You can use @DataElasticsearchTest
to test Elasticsearch applications.
By default, it configures an ElasticsearchRestTemplate
, scans for @Document
classes, and configures Spring Data Elasticsearch repositories.
Regular @Component
and @ConfigurationProperties
beans are not scanned when the @DataElasticsearchTest
annotation is used.
@EnableConfigurationProperties
can be used to include @ConfigurationProperties
beans.
(For more about using Elasticsearch with Spring Boot, see "data.adoc", earlier in this chapter.)
Tip
|
A list of the auto-configuration settings that are enabled by @DataElasticsearchTest can be found in the appendix.
|
The following example shows a typical setup for using Elasticsearch tests in Spring Boot:
code:MyDataElasticsearchTests
You can use the @DataJpaTest
annotation to test JPA applications.
By default, it scans for @Entity
classes and configures Spring Data JPA repositories.
If an embedded database is available on the classpath, it configures one as well.
SQL queries are logged by default by setting the spring.jpa.show-sql
property to true
.
This can be disabled using the showSql
attribute of the annotation.
Regular @Component
and @ConfigurationProperties
beans are not scanned when the @DataJpaTest
annotation is used.
@EnableConfigurationProperties
can be used to include @ConfigurationProperties
beans.
Tip
|
A list of the auto-configuration settings that are enabled by @DataJpaTest can be found in the appendix.
|
By default, data JPA tests are transactional and roll back at the end of each test. See the {spring-framework-docs}/testing/testcontext-framework/tx.html#testcontext-tx-enabling-transactions[relevant section] in the Spring Framework Reference Documentation for more details. If that is not what you want, you can disable transaction management for a test or for the whole class as follows:
code:MyNonTransactionalTests
Data JPA tests may also inject a {spring-boot-test-autoconfigure-module-code}/orm/jpa/TestEntityManager.java[TestEntityManager
] bean, which provides an alternative to the standard JPA EntityManager
that is specifically designed for tests.
Tip
|
TestEntityManager can also be auto-configured to any of your Spring-based test class by adding @AutoConfigureTestEntityManager .
When doing so, make sure that your test is running in a transaction, for instance by adding @Transactional on your test class or method.
|
A JdbcTemplate
is also available if you need that.
The following example shows the @DataJpaTest
annotation in use:
code:withoutdb/MyRepositoryTests
In-memory embedded databases generally work well for tests, since they are fast and do not require any installation.
If, however, you prefer to run tests against a real database you can use the @AutoConfigureTestDatabase
annotation, as shown in the following example:
code:withdb/MyRepositoryTests
@JdbcTest
is similar to @DataJpaTest
but is for tests that only require a DataSource
and do not use Spring Data JDBC.
By default, it configures an in-memory embedded database and a JdbcTemplate
.
Regular @Component
and @ConfigurationProperties
beans are not scanned when the @JdbcTest
annotation is used.
@EnableConfigurationProperties
can be used to include @ConfigurationProperties
beans.
Tip
|
A list of the auto-configurations that are enabled by @JdbcTest can be found in the appendix.
|
By default, JDBC tests are transactional and roll back at the end of each test. See the {spring-framework-docs}/testing/testcontext-framework/tx.html#testcontext-tx-enabling-transactions[relevant section] in the Spring Framework Reference Documentation for more details. If that is not what you want, you can disable transaction management for a test or for the whole class, as follows:
code:MyTransactionalTests
If you prefer your test to run against a real database, you can use the @AutoConfigureTestDatabase
annotation in the same way as for @DataJpaTest
.
(See "features.adoc".)
@DataJdbcTest
is similar to @JdbcTest
but is for tests that use Spring Data JDBC repositories.
By default, it configures an in-memory embedded database, a JdbcTemplate
, and Spring Data JDBC repositories.
Only AbstractJdbcConfiguration
subclasses are scanned when the @DataJdbcTest
annotation is used, regular @Component
and @ConfigurationProperties
beans are not scanned.
@EnableConfigurationProperties
can be used to include @ConfigurationProperties
beans.
Tip
|
A list of the auto-configurations that are enabled by @DataJdbcTest can be found in the appendix.
|
By default, Data JDBC tests are transactional and roll back at the end of each test. See the {spring-framework-docs}/testing/testcontext-framework/tx.html#testcontext-tx-enabling-transactions[relevant section] in the Spring Framework Reference Documentation for more details. If that is not what you want, you can disable transaction management for a test or for the whole test class as shown in the JDBC example.
If you prefer your test to run against a real database, you can use the @AutoConfigureTestDatabase
annotation in the same way as for @DataJpaTest
.
(See "features.adoc".)
@DataR2dbcTest
is similar to @DataJdbcTest
but is for tests that use Spring Data R2DBC repositories.
By default, it configures an in-memory embedded database, an R2dbcEntityTemplate
, and Spring Data R2DBC repositories.
Regular @Component
and @ConfigurationProperties
beans are not scanned when the @DataR2dbcTest
annotation is used.
@EnableConfigurationProperties
can be used to include @ConfigurationProperties
beans.
Tip
|
A list of the auto-configurations that are enabled by @DataR2dbcTest can be found in the appendix.
|
By default, Data R2DBC tests are not transactional.
If you prefer your test to run against a real database, you can use the @AutoConfigureTestDatabase
annotation in the same way as for @DataJpaTest
.
(See "features.adoc".)
You can use @JooqTest
in a similar fashion as @JdbcTest
but for jOOQ-related tests.
As jOOQ relies heavily on a Java-based schema that corresponds with the database schema, the existing DataSource
is used.
If you want to replace it with an in-memory database, you can use @AutoConfigureTestDatabase
to override those settings.
(For more about using jOOQ with Spring Boot, see "data.adoc".)
Regular @Component
and @ConfigurationProperties
beans are not scanned when the @JooqTest
annotation is used.
@EnableConfigurationProperties
can be used to include @ConfigurationProperties
beans.
Tip
|
A list of the auto-configurations that are enabled by @JooqTest can be found in the appendix.
|
@JooqTest
configures a DSLContext
.
The following example shows the @JooqTest
annotation in use:
code:MyJooqTests
JOOQ tests are transactional and roll back at the end of each test by default. If that is not what you want, you can disable transaction management for a test or for the whole test class as shown in the JDBC example.
You can use @DataMongoTest
to test MongoDB applications.
By default, it configures a MongoTemplate
, scans for @Document
classes, and configures Spring Data MongoDB repositories.
Regular @Component
and @ConfigurationProperties
beans are not scanned when the @DataMongoTest
annotation is used.
@EnableConfigurationProperties
can be used to include @ConfigurationProperties
beans.
(For more about using MongoDB with Spring Boot, see "data.adoc".)
Tip
|
A list of the auto-configuration settings that are enabled by @DataMongoTest can be found in the appendix.
|
The following class shows the @DataMongoTest
annotation in use:
code:MyDataMongoDbTests
You can use @DataNeo4jTest
to test Neo4j applications.
By default, it scans for @Node
classes, and configures Spring Data Neo4j repositories.
Regular @Component
and @ConfigurationProperties
beans are not scanned when the @DataNeo4jTest
annotation is used.
@EnableConfigurationProperties
can be used to include @ConfigurationProperties
beans.
(For more about using Neo4J with Spring Boot, see "data.adoc".)
Tip
|
A list of the auto-configuration settings that are enabled by @DataNeo4jTest can be found in the appendix.
|
The following example shows a typical setup for using Neo4J tests in Spring Boot:
code:propagation/MyDataNeo4jTests
By default, Data Neo4j tests are transactional and roll back at the end of each test. See the {spring-framework-docs}/testing/testcontext-framework/tx.html#testcontext-tx-enabling-transactions[relevant section] in the Spring Framework Reference Documentation for more details. If that is not what you want, you can disable transaction management for a test or for the whole class, as follows:
code:nopropagation/MyDataNeo4jTests
Note
|
Transactional tests are not supported with reactive access.
If you are using this style, you must configure @DataNeo4jTest tests as described above.
|
You can use @DataRedisTest
to test Redis applications.
By default, it scans for @RedisHash
classes and configures Spring Data Redis repositories.
Regular @Component
and @ConfigurationProperties
beans are not scanned when the @DataRedisTest
annotation is used.
@EnableConfigurationProperties
can be used to include @ConfigurationProperties
beans.
(For more about using Redis with Spring Boot, see "data.adoc".)
Tip
|
A list of the auto-configuration settings that are enabled by @DataRedisTest can be found in the appendix.
|
The following example shows the @DataRedisTest
annotation in use:
code:MyDataRedisTests
You can use @DataLdapTest
to test LDAP applications.
By default, it configures an in-memory embedded LDAP (if available), configures an LdapTemplate
, scans for @Entry
classes, and configures Spring Data LDAP repositories.
Regular @Component
and @ConfigurationProperties
beans are not scanned when the @DataLdapTest
annotation is used.
@EnableConfigurationProperties
can be used to include @ConfigurationProperties
beans.
(For more about using LDAP with Spring Boot, see "data.adoc".)
Tip
|
A list of the auto-configuration settings that are enabled by @DataLdapTest can be found in the appendix.
|
The following example shows the @DataLdapTest
annotation in use:
code:inmemory/MyDataLdapTests
In-memory embedded LDAP generally works well for tests, since it is fast and does not require any developer installation. If, however, you prefer to run tests against a real LDAP server, you should exclude the embedded LDAP auto-configuration, as shown in the following example:
code:server/MyDataLdapTests
You can use the @RestClientTest
annotation to test REST clients.
By default, it auto-configures Jackson, GSON, and Jsonb support, configures a RestTemplateBuilder
and a RestClient.Builder
, and adds support for MockRestServiceServer
.
Regular @Component
and @ConfigurationProperties
beans are not scanned when the @RestClientTest
annotation is used.
@EnableConfigurationProperties
can be used to include @ConfigurationProperties
beans.
Tip
|
A list of the auto-configuration settings that are enabled by @RestClientTest can be found in the appendix.
|
The specific beans that you want to test should be specified by using the value
or components
attribute of @RestClientTest
.
When using a RestTemplateBuilder
in the beans under test and RestTemplateBuilder.rootUri(String rootUri)
has been called when building the RestTemplate
, then the root URI should be omitted from the MockRestServiceServer
expectations as shown in the following example:
code:MyRestTemplateServiceTests
When using a RestClient.Builder
in the beans under test, or when using a RestTemplateBuilder
without calling rootUri(String rootURI)
, the full URI must be used in the MockRestServiceServer
expectations as shown in the following example:
code:MyRestClientServiceTests
You can use the @AutoConfigureRestDocs
annotation to use {spring-restdocs}[Spring REST Docs] in your tests with Mock MVC, REST Assured, or WebTestClient.
It removes the need for the JUnit extension in Spring REST Docs.
@AutoConfigureRestDocs
can be used to override the default output directory (target/generated-snippets
if you are using Maven or build/generated-snippets
if you are using Gradle).
It can also be used to configure the host, scheme, and port that appears in any documented URIs.
@AutoConfigureRestDocs
customizes the MockMvc
bean to use Spring REST Docs when testing servlet-based web applications.
You can inject it by using @Autowired
and use it in your tests as you normally would when using Mock MVC and Spring REST Docs, as shown in the following example:
code:MyUserDocumentationTests
If you require more control over Spring REST Docs configuration than offered by the attributes of @AutoConfigureRestDocs
, you can use a RestDocsMockMvcConfigurationCustomizer
bean, as shown in the following example:
code:MyRestDocsConfiguration
If you want to make use of Spring REST Docs support for a parameterized output directory, you can create a RestDocumentationResultHandler
bean.
The auto-configuration calls alwaysDo
with this result handler, thereby causing each MockMvc
call to automatically generate the default snippets.
The following example shows a RestDocumentationResultHandler
being defined:
code:MyResultHandlerConfiguration
@AutoConfigureRestDocs
can also be used with WebTestClient
when testing reactive web applications.
You can inject it by using @Autowired
and use it in your tests as you normally would when using @WebFluxTest
and Spring REST Docs, as shown in the following example:
code:MyUsersDocumentationTests
If you require more control over Spring REST Docs configuration than offered by the attributes of @AutoConfigureRestDocs
, you can use a RestDocsWebTestClientConfigurationCustomizer
bean, as shown in the following example:
code:MyRestDocsConfiguration
If you want to make use of Spring REST Docs support for a parameterized output directory, you can use a WebTestClientBuilderCustomizer
to configure a consumer for every entity exchange result.
The following example shows such a WebTestClientBuilderCustomizer
being defined:
code:MyWebTestClientBuilderCustomizerConfiguration
@AutoConfigureRestDocs
makes a RequestSpecification
bean, preconfigured to use Spring REST Docs, available to your tests.
You can inject it by using @Autowired
and use it in your tests as you normally would when using REST Assured and Spring REST Docs, as shown in the following example:
code:MyUserDocumentationTests
If you require more control over Spring REST Docs configuration than offered by the attributes of @AutoConfigureRestDocs
, a RestDocsRestAssuredConfigurationCustomizer
bean can be used, as shown in the following example:
code:MyRestDocsConfiguration
You can use @WebServiceClientTest
to test applications that call web services using the Spring Web Services project.
By default, it configures a mock WebServiceServer
bean and automatically customizes your WebServiceTemplateBuilder
.
(For more about using Web Services with Spring Boot, see "io.adoc".)
Tip
|
A list of the auto-configuration settings that are enabled by @WebServiceClientTest can be found in the appendix.
|
The following example shows the @WebServiceClientTest
annotation in use:
code:MyWebServiceClientTests
You can use @WebServiceServerTest
to test applications that implement web services using the Spring Web Services project.
By default, it configures a MockWebServiceClient
bean that can be used to call your web service endpoints.
(For more about using Web Services with Spring Boot, see "io.adoc".)
Tip
|
A list of the auto-configuration settings that are enabled by @WebServiceServerTest can be found in the appendix.
|
The following example shows the @WebServiceServerTest
annotation in use:
code:MyWebServiceServerTests
Each slice provides one or more @AutoConfigure…
annotations that namely defines the auto-configurations that should be included as part of a slice.
Additional auto-configurations can be added on a test-by-test basis by creating a custom @AutoConfigure…
annotation or by adding @ImportAutoConfiguration
to the test as shown in the following example:
code:MyJdbcTests
Note
|
Make sure to not use the regular @Import annotation to import auto-configurations as they are handled in a specific way by Spring Boot.
|
Alternatively, additional auto-configurations can be added for any use of a slice annotation by registering them in a file stored in META-INF/spring
as shown in the following example:
com.example.IntegrationAutoConfiguration
In this example, the com.example.IntegrationAutoConfiguration
is enabled on every test annotated with @JdbcTest
.
Tip
|
You can use comments with # in this file.
|
Tip
|
A slice or @AutoConfigure… annotation can be customized this way as long as it is meta-annotated with @ImportAutoConfiguration .
|
If you structure your code in a sensible way, your @SpringBootApplication
class is used by default as the configuration of your tests.
It then becomes important not to litter the application’s main class with configuration settings that are specific to a particular area of its functionality.
Assume that you are using Spring Data MongoDB, you rely on the auto-configuration for it, and you have enabled auditing.
You could define your @SpringBootApplication
as follows:
code:MyApplication
Because this class is the source configuration for the test, any slice test actually tries to enable Mongo auditing, which is definitely not what you want to do.
A recommended approach is to move that area-specific configuration to a separate @Configuration
class at the same level as your application, as shown in the following example:
code:MyMongoConfiguration
Note
|
Depending on the complexity of your application, you may either have a single @Configuration class for your customizations or one class per domain area.
The latter approach lets you enable it in one of your tests, if necessary, with the @Import annotation.
See this how-to section for more details on when you might want to enable specific @Configuration classes for slice tests.
|
Test slices exclude @Configuration
classes from scanning.
For example, for a @WebMvcTest
, the following configuration will not include the given WebMvcConfigurer
bean in the application context loaded by the test slice:
code:MyWebConfiguration
The configuration below will, however, cause the custom WebMvcConfigurer
to be loaded by the test slice.
code:MyWebMvcConfigurer
Another source of confusion is classpath scanning. Assume that, while you structured your code in a sensible way, you need to scan an additional package. Your application may resemble the following code:
code:scan/MyApplication
Doing so effectively overrides the default component scan directive with the side effect of scanning those two packages regardless of the slice that you chose.
For instance, a @DataJpaTest
seems to suddenly scan components and user configurations of your application.
Again, moving the custom directive to a separate class is a good way to fix this issue.
Tip
|
If this is not an option for you, you can create a @SpringBootConfiguration somewhere in the hierarchy of your test so that it is used instead.
Alternatively, you can specify a source for your test, which disables the behavior of finding a default one.
|
Spock 2.2 or later can be used to test a Spring Boot application.
To do so, add a dependency on a -groovy-4.0
version of Spock’s spock-spring
module to your application’s build.
spock-spring
integrates Spring’s test framework into Spock.
See the documentation for Spock’s Spring module for further details.
The Testcontainers library provides a way to manage services running inside Docker containers. It integrates with JUnit, allowing you to write a test class that can start up a container before any of the tests run. Testcontainers is especially useful for writing integration tests that talk to a real backend service such as MySQL, MongoDB, Cassandra and others.
Testcontainers can be used in a Spring Boot test as follows:
code:vanilla/MyIntegrationTests
This will start up a docker container running Neo4j (if Docker is running locally) before any of the tests are run. In most cases, you will need to configure the application to connect to the service running in the container.
A service connection is a connection to any remote service. Spring Boot’s auto-configuration can consume the details of a service connection and use them to establish a connection to a remote service. When doing so, the connection details take precedence over any connection-related configuration properties.
When using Testcontainers, connection details can be automatically created for a service running in a container by annotating the container field in the test class.
code:MyIntegrationTests
Thanks to @ServiceConnection
, the above configuration allows Neo4j-related beans in the application to communicate with Neo4j running inside the Testcontainers-managed Docker container.
This is done by automatically defining a Neo4jConnectionDetails
bean which is then used by the Neo4j auto-configuration, overriding any connection-related configuration properties.
Note
|
You’ll need to add the spring-boot-testcontainers module as a test dependency in order to use service connections with Testcontainers.
|
Service connection annotations are processed by ContainerConnectionDetailsFactory
classes registered with spring.factories
.
A ContainerConnectionDetailsFactory
can create a ConnectionDetails
bean based on a specific Container
subclass, or the Docker image name.
The following service connection factories are provided in the spring-boot-testcontainers
jar:
Connection Details | Matched on |
---|---|
|
Containers named "symptoma/activemq" |
|
Containers of type |
|
Containers of type |
|
Containers of type |
|
Containers of type |
|
Containers of type |
|
Containers of type |
|
Containers of type |
|
Containers of type |
|
Containers of type |
|
Containers named "otel/opentelemetry-collector-contrib" |
|
Containers named "otel/opentelemetry-collector-contrib" |
|
Containers of type |
|
Containers of type |
|
Containers of type |
|
Containers named "redis" |
|
Containers named "openzipkin/zipkin" |
Tip
|
By default all applicable connection details beans will be created for a given If you want to create only a subset of the applicable types, you can use the |
By default Container.getDockerImageName()
is used to obtain the name used to find connection details.
This works as long as Spring Boot is able to get the instance of the Container
, which is the case when using a static
field like in the example above.
If you’re using a @Bean
method, Spring Boot won’t call the bean method to get the Docker image name, because this would cause eager initialization issues.
Instead, the return type of the bean method is used to find out which connection detail should be used.
This works as long as you’re using typed containers, e.g. Neo4jContainer
or RabbitMQContainer
.
This stops working if you’re using GenericContainer
, e.g. with Redis, as shown in the following example:
code:MyRedisConfiguration
Spring Boot can’t tell from GenericContainer
which container image is used, so the name
attribute from @ServiceConnection
must be used to provide that hint.
You can also can use the name
attribute of @ServiceConnection
to override which connection detail will be used, for example when using custom images.
If you are using the Docker image registry.mycompany.com/mirror/myredis
, you’d use @ServiceConnection(name="redis")
to ensure RedisConnectionDetails
are created.
A slightly more verbose but also more flexible alternative to service connections is @DynamicPropertySource
.
A static @DynamicPropertySource
method allows adding dynamic property values to the Spring Environment.
code:MyIntegrationTests
The above configuration allows Neo4j-related beans in the application to communicate with Neo4j running inside the Testcontainers-managed Docker container.
A few test utility classes that are generally useful when testing your application are packaged as part of spring-boot
.
ConfigDataApplicationContextInitializer
is an ApplicationContextInitializer
that you can apply to your tests to load Spring Boot application.properties
files.
You can use it when you do not need the full set of features provided by @SpringBootTest
, as shown in the following example:
code:MyConfigFileTests
Note
|
Using ConfigDataApplicationContextInitializer alone does not provide support for @Value("${…}") injection.
Its only job is to ensure that application.properties files are loaded into Spring’s Environment .
For @Value support, you need to either additionally configure a PropertySourcesPlaceholderConfigurer or use @SpringBootTest , which auto-configures one for you.
|
TestPropertyValues
lets you quickly add properties to a ConfigurableEnvironment
or ConfigurableApplicationContext
.
You can call it with key=value
strings, as follows:
code:MyEnvironmentTests
OutputCapture
is a JUnit Extension
that you can use to capture System.out
and System.err
output.
To use it, add @ExtendWith(OutputCaptureExtension.class)
and inject CapturedOutput
as an argument to your test class constructor or test method as follows:
code:MyOutputCaptureTests
TestRestTemplate
is a convenience alternative to Spring’s RestTemplate
that is useful in integration tests.
You can get a vanilla template or one that sends Basic HTTP authentication (with a username and password).
In either case, the template is fault tolerant.
This means that it behaves in a test-friendly way by not throwing exceptions on 4xx and 5xx errors.
Instead, such errors can be detected through the returned ResponseEntity
and its status code.
Tip
|
Spring Framework 5.0 provides a new WebTestClient that works for WebFlux integration tests and both WebFlux and MVC end-to-end testing.
It provides a fluent API for assertions, unlike TestRestTemplate .
|
It is recommended, but not mandatory, to use the Apache HTTP Client (version 5.1 or better).
If you have that on your classpath, the TestRestTemplate
responds by configuring the client appropriately.
If you do use Apache’s HTTP client, some additional test-friendly features are enabled:
-
Redirects are not followed (so you can assert the response location).
-
Cookies are ignored (so the template is stateless).
TestRestTemplate
can be instantiated directly in your integration tests, as shown in the following example:
code:MyTests
Alternatively, if you use the @SpringBootTest
annotation with WebEnvironment.RANDOM_PORT
or WebEnvironment.DEFINED_PORT
, you can inject a fully configured TestRestTemplate
and start using it.
If necessary, additional customizations can be applied through the RestTemplateBuilder
bean.
Any URLs that do not specify a host and port automatically connect to the embedded server, as shown in the following example:
code:MySpringBootTests