Spring Boot Test Slices: Overview and Usage

Last Updated:  July 25, 2023 | Published: August 31, 2020

Spring Boot offers great support to test different slices (web, database, etc.) of your application. This allows you to write tests for specific parts of your application in isolation without bootstrapping the whole Spring Context. Technically this is achieved by creating a Spring Context with only a subset of beans by applying only specific auto-configurations. Continue reading to get to know the most important test slice annotations to write isolated and fast tests.

Testing the Web Layer With @WebMvcTest

Using this annotation, you'll get a Spring Context that includes components required for testing Spring MVC parts of your application.

What's part of the Spring Test Context: @Controller, @ControllerAdvice, @JsonComponent, Converter, Filter, WebMvcConfigurer

What's not part of the Spring Test Context: @Service, @Component, @Repository beans

Furthermore, there is also great support if you secure your endpoints with Spring Security. The annotation will auto-configure your security rules, and if you include the Spring Security Test dependency, you can easily mock the authenticated user.

As this annotation provides a mocked servlet environment, there is no port to access your application with, e.g., a RestTemplate. Therefore, you rather use the auto-configured MockMvc to access your endpoints:

Usually, you mock any dependent bean of your controller endpoint using @MockBean.

If you write reactive applications with WebFlux, there is also @WebFluxTest.

Testing your JPA Components With @DataJpaTest

With this annotation, you can test any JPA-related parts of your application. A good example is to verify that a native query is working as expected.

What's part of the Spring Test Context: @Repository, EntityManager, TestEntityManager, DataSource

What's not part of the Spring Test Context: @Service, @Component, @Controller beans

By default, this annotation tries to auto-configure use an embedded database (e.g., H2) as the DataSource:

While an in-memory database might not be a good choice to verify a native query using proprietary features, you can disable this auto-configuration with:

and use, e.g., Testcontainers to create a PostgreSQL database for testing.

In addition to the auto-configuration, all tests run inside a transaction and get rolled back after their execution.

Testing JDBC Access With @JdbcTest

If your application uses the JdbcTemplate instead of JPA for the database access, Spring Boot also covers testing this slice of your application.

What's part of the Spring Test Context: JdbcTemplate, DataSource

What's not part of the Spring Test Context: @Service, @Component, @Controller, @Repository beans

Similar to @DataJpaTest, this annotation auto-configures an embedded database for you.

Testing MongoDB Access With @DataMongoTest

Next, if your application does not use a relational database but rather a NoSQL MongoDB database, you get testing support for this.

What's part of the Spring Test Context: MongoTemplate, CrudRepository for MongoDB documents

What's not part of the Spring Test Context: @Service, @Component, @Controller

This annotation auto-configures an embedded MongoDB database for you, like the test slice annotations for JPA and JDBC. Therefore you can use the following dependency:

And then start testing your MongoDB components:

Testing JSON Serialization with @JsonTest

What comes next is a more unknown test slice annotation that helps to test JSON serialization: @JsonTest

What's part of the Spring Test Context: @JsonComponent,ObjectMapper, Module from Jackson or similar components when using JSONB or GSON

What's not part of the Spring Test Context: @Service, @Component, @Controller, @Repository

If you have a more complex serialization logic for your Java classes or make use of several Jackson annotations:

You can use this test slice to verify the JSON serialization of your Spring Boot application:

Find further information on the @JsonTest annotation in a previous blog post.

Testing HTTP Clients With @RestClientTest

Next comes a hidden gem when you want to test your HTTP clients with a local HTTP server.

What's part of the Spring Test Context: your HTTP client using RestTemplateBuilder, MockRestServiceServer, Jackson auto-configuration

What's not part of the Spring Test Context: @Service, @Component, @Controller, @Repository

Using the MockRestServiceServer you can now mock different HTTP responses from the remote system:

You can find a demonstration of this annotation on YouTube.

If your application makes use of the WebClient, you can achieve something similar.

Testing the Entire Application With @SpringBootTest

Finally, the last annotation allows writing tests against the whole application context.

What's part of the Spring Test Context: everything, TestRestTemplate (if you start the embedded servlet container)

What's not part of the Spring Test Context: –

You can combine this annotation with other @AutoConfigure annotations (e.g. @AutoConfigureTestDatabase) to fine-tune the application context.

As now all beans are part of the Spring Context, you have to access all external resources that your application requires for startup/test execution. Again, Testcontainers can help a lot here.

By default, you'll still get a mocked servlet environment and won't occupy any local port.

If you want to start the embedded servlet container (Tomcat in most cases), you can override the webEnvironment attribute:

This will also auto-configure a TestRestTemplate for you to access your application on the random port. You can find more in-depth information about the @SpringBootTest annotation for writing integration tests in another guide of mine.

Write Your Own Spring Boot Test Slice

If there's no out-of-the-box test slice available for your specific tech stack, you can write your own Spring Boot test slice.

A good example may be a test slice for Kafka listeners or any other message queue.

For a blueprint on how to write your custom Spring Boot test slice, take a look at how the Spring Cloud AWS project implemented @SqsTest to test SQS listeners in isolation.

You can find the source code for these examples on GitHub.

Have fun using Spring Boot Test slice annotations,

Phil

>