The @SpringBootTest annotation in Spring Boot creates integration tests by loading the entire application context. It connects the application configuration with the test framework, so the tests verify the behavior of the application in an environment similar to production.
Unlike unit testing, which isolates individual components, @SpringBootTest enables integration testing, which checks that the interaction between components works as expected.
1. @SpringBootTest Annotation
By default, @SpringBootTest loads the entire Spring context, including configurations, beans and dependencies, so the application behaves as it would in a production-like environment. We can adjust the context loading with profiles or specific configurations, such as application-test.yml for integration testing.
The @SpringBootTest annotation adds the following features to the regular Spring TestContext that the @ContextConfiguration(classes=…) annotation of spring-test provides.
- It searches for a @SpringBootConfiguration class when no nested @Configuration class is used and no explicit classes are specified.
- It lets us define custom environment properties with the properties attribute.
- It supports different webEnvironment modes, including a fully running web server that listens on a defined or random port.
- It registers a TestRestTemplate or WebTestClient bean (or both) for web tests that use a fully running web server.
1.1. Using the webEnvironment Attribute
The webEnvironment attribute controls the type of web environment used during testing. It decides whether a full web server starts or a mock environment is used.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
The webEnvironment attribute supports four values.
| Attribute | Description |
|---|---|
| MOCK | Default mode where no server is started. Ideal for controller-level tests using MockMvc. |
| RANDOM_PORT | Starts the application on a random port. Useful for avoiding conflicts during parallel testing. |
| DEFINED_PORT | Starts the server on a predefined port specified in application.properties. |
| NONE | Prevents the server and web context from starting. Used for non-web application (e.g., batch processing or messaging systems) tests. |
1.2. Managing Database State During Tests
When we test with real databases, we use @Transactional so that each test starts with the same database state. The annotation rolls back the database changes after each test, so the tests do not interfere with each other.
In the following example, @Transactional on the test methods rolls back the transaction after each test completes, so the database has the same state as before the test.
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@Transactional
public class MyServiceTest {
@Autowired
private MyService myService;
@Test
public void testMyServiceMethod() {
// ... your test logic ...
myService.doSomething();
// ... assertions ...
}
}
If the tests need a database setup, such as inserting test data, we use @BeforeEach or @BeforeAll methods with @Transactional disabled, to avoid rollbacks that would interfere with the subsequent tests.
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class MyServiceTest {
@Autowired
private MyService myService;
@Autowired
private MyRepository myRepository;
@BeforeEach
public void setUp() {
myRepository.save(new MyEntity());
}
@Test
@Transactional
public void testMyServiceMethod() {
// ... your test logic ...
myService.doSomething();
// ... assertions ...
}
}
2. Using @SpringBootTest
The @SpringBootTest annotation mimics the processes that Spring Boot adds to create the context. For example, it decides what to scan based on the package structure and loads external configurations from predefined locations. It also optionally runs the auto-configuration starters.
We can see that @SpringBootTest starts and configures almost the whole application before the test begins. So we use it to write integration tests that use the application processes and external dependencies.
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
public class SpringBootDemoApplicationTests
{
@LocalServerPort
int randomServerPort;
//---- tests -----
}
2.1. Testing a REST API Endpoint with @SpringBootTest
A JUnit 5 test with @SpringBootTest can test a REST API endpoint of the application.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ApiIntegrationTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
void testGetEndpoint() {
ResponseEntity<String> response = restTemplate.getForEntity("/api/items", String.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertNotNull(response.getBody());
}
}
2.2. Testing a Service Layer with Mock Dependencies
A test for a service class can replace its dependencies with mocks.
@SpringBootTest
class ServiceLayerTest {
@MockBean
private SomeRepository repository;
@Autowired
private SomeService service;
@Test
void testServiceMethod() {
when(repository.findById(1L)).thenReturn(Optional.of(new Item("Mock Item")));
Item result = service.getItemById(1L);
assertEquals("Mock Item", result.getName());
}
}
2.3. Testing Data Persistence with an Embedded Database
A test for a repository class interacts with a real database.
@SpringBootTest
class RepositoryTest {
@Autowired
private ItemRepository repository;
@Test
@Transactional
void testSaveAndFind() {
Item item = repository.save(new Item("Test Item"));
Optional<Item> fetchedItem = repository.findById(item.getId());
assertTrue(fetchedItem.isPresent());
assertEquals("Test Item", fetchedItem.get().getName());
}
}
3. Loading Application Context Partially
By default, the @SpringBootTest annotation loads the whole application. It is better to limit the application context to the Spring components that participate in the test scenario.
3.1. Using classes Attribute
The classes attribute specifies the annotated classes that load the ApplicationContext.
@SpringBootTest(classes = {EmployeeRepository.class, EmployeeService.class})
public class SpringBootDemoApplicationTests {
@Autowired
private EmployeeService employeeService;
//---- tests -----
}
3.2. Test Slice Annotations
For unit tests, we do not use the @SpringBootTest annotation. We use the specialized Spring Boot test annotations instead, which test a particular slice of the application.
The slice annotations disable the full auto-configuration and apply only the configuration relevant to specific layers of the codebase.
Each slice annotation configures only the beans of its own layer.
| Annotation | Description | Key Features |
|---|---|---|
| @WebFluxTest | Used for typical Spring WebFlux tests, focusing only on Spring WebFlux components. | – Works with @RunWith(SpringRunner.class). – Auto-configures a WebTestClient. – Excludes other Spring components for focused testing. |
| @JdbcTest | Used for testing JDBC-based components. | – Configures an embedded in-memory database. – Configures JdbcTemplate. – Tests are transactional and roll back at the end. |
| @DataMongoTest | Used for testing MongoDB components. | – Uses an embedded MongoDB (if driver is available). – Configures MongoTemplate. – Scans @Document classes. – Configures Spring Data MongoDB repositories. |
| @DataRedisTest | Used for testing Redis applications. | – Scans for @RedisHash classes. – Configures Spring Data Redis repositories. |
| @DataLdapTest | Used for testing LDAP applications. | – Configures an in-memory LDAP (if available). – Configures LdapTemplate. – Scans for @Entry classes. – Configures Spring Data LDAP repositories. |
| @RestClientTest | Used for testing REST clients. | – Auto-configures dependencies like Jackson, GSON, and Jsonb. – Configures RestTemplateBuilder. – Adds support for MockRestServiceServer by default. |
| @JooqTest | Used for testing jOOQ-based components. | – Specifically designed for testing jOOQ components. – Scans and configures relevant jOOQ-related beans. |
4. Conclusion
We use the @SpringBootTest annotation to write integration tests in a Spring Boot application. By default, it scans and loads the whole application context and all Spring Boot-related auto-configurations.
To write unit tests for a few specific sections of the application, we use the specialized …Test annotations from section 3.2.
Drop me your questions about how to do integration testing in Spring Boot in the comments.
Happy Learning !!