Spring Boot Testing : Basic Concepts and Categories of Tests
Tags: java, springboot, spring, testing
Published: 2024-05-01 18:27:12

Spring Boot provides many features for testing purpose, and with this large panel of choices, Developers might get confused about each one’s intend, leading them to use features that are not suitable for specific situations, and as a result they end up with tests taking longer to run than intended. This blog aims to shed lights on the different ways with which we can test a modern Spring Boot application.

**Spring Boot Starter for Testing**

Most of the dependencies that are going to be used for testing, are provided by the Spring Boot team in the format of a starter, in Maven this starter is identified by the following attributes :

```
<dependency>  
  <groupId>org.springframework.boot</groupId>  
  <artifactId>spring-boot-starter-test</artifactId>  
  <version>{spring.boot.starter.test.version}</version>  
  <scope>test</scope>  
</dependency>
```
**Categories of Tests in Spring Boot**

***Unit Test***

A Unit Test is about testing the behaviors or the methods of a class in isolation of the classes on which it depends.

In the context of Spring Boot, a unit test makes sense for only some classes of the application such as business logic or mapping classes.

Writing and running unit tests does not require Spring Boot, instead it only needs tools like JUnit, Mockito, and AssertJ.

***Integration Test***

Unit tests are not enough, sometimes we will need to test behaviors that involve more than one class, examples for these could be testing the web layer and that the endpoints respond correcltly to the requests or testing the data layer and that data is stored correctly into a database, that is where integration tests come into play.

An integration test requires Spring Boot to start the application, trigger the auto-configurations as well as loading the application context, that is why Spring Boot is a must when it comes to integration tests in addition to tools such as JUnit, Mockito and AssertJ.

**Categories of Integration Tests in Spring Boot**

***Broad Integration Test (End To End Test)***

A Broad Integration Test is about testing a behavior that involves vlasses accross mostly all layers of the application used for serving a client request, from controllers to repositories.

Spring Boot provides the @SpringBootTest annotation for creating the application context after scanning the bean defintions from the user configuration and auto-configuration classes.

A broad integration test can either be executed using a mock web environment or using a real web server, the difference is that with the second approach we will have to send real HTTP requests for tests.
We generally don’t have to connect to extenal services or external databases, a web service should be mocked and a database is always replaced with an in-memory database or even with a real instance running inside a Docker conrainer using Testcontainers

***Narrow Integration Test (Component Test)***

A Narrow Integration Test is about testing a behavior involving only classes from a specific layer of the application, such as testing the web layer only or the data layer only. the good thing about those tests is that Spring Boot will make the application context scan for only parts of the user configuration and parts of the auto-configurations, and as a result only a slice of the configuration will be loaded in the application context, this makes the test much faster than loading all the configuration like what is performed with a Broad Integration Test.

The most commonly used annotations provided by Spring Boot for narrow integration testing are :

- @WebMvcTest for testing the web layer
- @DataJpaTest for testing the data layer

There are other annotations for other parts such as @JsonTest, @WebFluxTest, @DataJdbcTest, @DataMongoTest and @RestClientTest