Clean • Professional
Testing is a crucial part of software development. In Spring Boot, annotations make testing simple, fast, and reliable. Understanding these test annotations helps you write robust unit, integration, and web tests efficiently.
Spring Boot Test Annotations are special Java annotations provided by Spring Boot that make testing your application easier, faster, and more organized.
In Spring Boot, testing can involve unit tests, integration tests, web layer tests, database tests, and security tests. Each of these tests may need a slightly different setup, and Spring Boot test annotations help you:
Spring Boot Test Annotations are tools that tell Spring Boot how to run your tests efficiently and correctly.
Spring Boot provides several test annotations to help developers write unit tests, integration tests, web tests, database tests, and security tests easily. Using the right annotation ensures faster tests, better maintainability, and realistic testing.
@SpringBootTest@SpringBootTest is the go-to annotation for full integration testing in Spring Boot. It loads the complete Spring application context, allowing you to test all layers of your application together.
Key Points:
Example:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
classUserApiE2ETest {
@Autowired
private TestRestTemplate restTemplate;
@Test
voidtestCreateUser() {
ResponseEntity<User> response = restTemplate.postForEntity("/users",newUser("Alice"), User.class);
Assertions.assertEquals(HttpStatus.OK, response.getStatusCode());
}
}
@WebMvcTest@WebMvcTest is used for testing the web layer only. It does not load the full application context, making your tests fast and focused on controllers and REST endpoints.
Key Points:
@MockBean to mock service dependenciesExample:
@WebMvcTest(UserController.class)
classUserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@Test
voidtestGetUser()throws Exception {
Mockito.when(userService.getUserById(1L)).thenReturn(newUser("Alice"));
mockMvc.perform(get("/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("Alice"));
}
}
@DataJpaTest@DataJpaTest is designed for repository testing. It loads only the JPA components and configures an in-memory database, allowing you to test CRUD operations and queries efficiently.
Key Points:
Example:
@DataJpaTest
classUserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
voidtestFindByName() {
userRepository.save(newUser("Alice"));
Userfound= userRepository.findByName("Alice");
Assertions.assertNotNull(found);
}
}
@MockBean@MockBean is used to mock Spring beans in your test context. It allows you to replace real components with mock implementations for isolated testing.
Key Points:
Example:
@MockBean
private UserService userService;
@SpyBean@SpyBean wraps an existing Spring bean with a Mockito spy, allowing you to monitor interactions while still using the real implementation.
Key Points:
Example:
@SpyBean
private UserService userService;
@TestConfiguration@TestConfiguration allows you to define beans specifically for testing. Unlike a regular @Configuration, these beans are only loaded during tests.
Key Points:
Example:
@TestConfiguration
staticclassTestConfig {
@Bean
public UserServiceuserService() {
returnnewUserService();
}
}
@TestPropertySource@TestPropertySource allows you to override or add properties in the Spring Environment specifically for tests.
Example:
@TestPropertySource(properties = "app.feature.enabled=true")
@SpringBootTest
classFeatureTest {}
@ExtendWith(MockitoExtension.class)Integrates Mockito into JUnit 5 tests for mocking dependencies without loading the Spring context.
Key Points:
@Mock and @InjectMocksExample:
@ExtendWith(MockitoExtension.class)
classUserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
voidtestGetUserById() {
Mockito.when(userRepository.findById(1L)).thenReturn(Optional.of(newUser("Alice")));
Userresult= userService.getUserById(1L);
Assertions.assertEquals("Alice", result.getName());
}
}
@AutoConfigureMockMvcUsed with @SpringBootTest to auto-configure MockMvc for testing controllers in a fully loaded Spring context.
Key Points:
Example:
@SpringBootTest
@AutoConfigureMockMvc
classUserControllerIntegrationTest {
@Autowired
private MockMvc mockMvc;
@Test
voidtestGetUsers()throws Exception {
mockMvc.perform(get("/users"))
.andExpect(status().isOk());
}
}
@WithMockUserUsed for Spring Security testing by simulating a logged-in user.
Key Points:
@SpringBootTest or @WebMvcTestExample:
@WithMockUser(username = "admin", roles = "ADMIN")
@Test
voidadminAccessTest()throws Exception {
mockMvc.perform(get("/admin/dashboard"))
.andExpect(status().isOk());
}
@TestcontainersRuns integration tests with real Docker containers for databases, message brokers, or other services.
Key Points:
@SpringBootTestExample:
@Testcontainers
@SpringBootTest
classUserServiceTest {
@Container
static PostgreSQLContainer<?> postgres =newPostgreSQLContainer<>("postgres:15");
@Autowired
private UserRepository userRepository;
@Test
voidtestSaveUser() {
Useruser=newUser("Alice");
userRepository.save(user);
Assertions.assertEquals(1, userRepository.count());
}
}
@AutoConfigureWireMockMocks external HTTP APIs to prevent calling real services.
Key Points:
@SpringBootTest for integration testingExample:
@AutoConfigureWireMock(port = 0)
@SpringBootTest
classPaymentClientTest {
@Autowired
private PaymentService paymentService;
@Test
voidtestPaymentProcessing() {
stubFor(post(urlEqualTo("/payments"))
.willReturn(aResponse()
.withStatus(200)
.withBody("{\\"status\\":\\"success\\"}")));
PaymentResponseresponse= paymentService.processPayment(100);
Assertions.assertEquals("success", response.getStatus());
}
}
@SpringBootTest vs @WebMvcTest vs @DataJpaTest| Feature | @SpringBootTest | @WebMvcTest | @DataJpaTest |
|---|---|---|---|
| Layers Loaded | All layers: Controller, Service, Repository, DB | Only Web layer: Controller, Filter | Only Repository / JPA / Database layer |
| Database | Real DB or in-memory DB | No DB (mock dependencies with @MockBean) | In-memory DB by default (H2) |
| Speed | Slow | Fast | Fast |
| Use Case | Full integration / end-to-end tests | Controller / REST API testing | Repository / database testing |
| Dependencies | Loads all beans | Only web beans loaded; other dependencies mocked | Only JPA beans loaded; services not included |
The Spring Framework provides a set of annotations beyond Spring Boot’s core test annotations. These help control the application context, manage transactions, run SQL scripts, and monitor test lifecycle events. They are essential for integration tests, complex application contexts, and transactional scenarios.
@BootstrapWithCustomizes how the Spring test context is bootstrapped for a test class.
Key Points:
Example:
@BootstrapWith(CustomTestContextBootstrapper.class)
classCustomBootstrapTest {
@Test
voidtestSomething() {
// Custom context setup applied
}
}
@ContextConfigurationLoads specific configuration classes or XML files for tests.
Key Points:
Example:
@ContextConfiguration(classes = {AppConfig.class, TestConfig.class})
classAppServiceTest {
@Autowired
private UserService userService;
@Test
voidtestUserCreation() {
assertNotNull(userService);
}
}
@WebAppConfigurationMarks a test as a web application test and sets the root directory for web resources.
Key Points:
WebApplicationContext.MockMvc for controller tests.Example:
@WebAppConfiguration
@ContextConfiguration(classes = WebAppConfig.class)
classWebControllerTest {
@Autowired
private WebApplicationContext wac;
@Test
voidtestController() {
MockMvcmockMvc= MockMvcBuilders.webAppContextSetup(wac).build();
mockMvc.perform(get("/users"))
.andExpect(status().isOk());
}
}
@ActiveProfilesActivates specific Spring profiles for tests.
Key Points:
Example:
@ActiveProfiles("test")
@SpringBootTest
classProfileBasedTest {
@Autowired
private UserRepository userRepository;
@Test
voidtestProfileBeans() {
assertTrue(userRepositoryinstanceof TestUserRepository);
}
}
@TestExecutionListenersRegisters custom listeners for test lifecycle events.
Key Points:
Example:
@TestExecutionListeners(listeners = MyCustomTestListener.class)
@SpringBootTest
classTestListenerExample {
@Test
voidtestSomething() {
// Listener logic runs automatically
}
}
@Sql / @SqlConfigRun SQL scripts before or after tests to prepare or clean database state.
Key Points:
@SqlConfig allows custom data source, encoding, or transaction behavior.Example:
@Sql(scripts = "/test-data.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
@DataJpaTest
classUserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
voidtestInsertUser() {
userRepository.save(newUser("Alice"));
assertEquals(1, userRepository.count());
}
}
@Commit / @RollbackControl transaction behavior in tests.
Key Points:
@Commit to persist changes or @Rollback to explicitly roll back.Example:
@SpringBootTest
@Transactional
classTransactionTest {
@Test
@Commit
voidtestCommitTransaction() {
userRepository.save(newUser("Bob"));
}
@Test
@Rollback
voidtestRollbackTransaction() {
userRepository.save(newUser("Charlie"));
}
}
@DirtiesContextMarks the Spring context as dirty, forcing it to reload for subsequent tests.
Key Points:
Example:
@SpringBootTest
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
classDirtyContextTest {
@Test
voidmodifyBean() {
myService.setValue(42);
}
}
@RecordApplicationEventsRecords Spring events published during a test.
Key Points:
Example:
@SpringBootTest
@RecordApplicationEvents
classEventTest {
@Autowired
private ApplicationEventPublisher publisher;
@Autowired
private ApplicationEvents events;
@Test
voidtestEventPublishing() {
publisher.publishEvent(newCustomEvent(this,"Hello"));
assertThat(events.stream(CustomEvent.class))
.anyMatch(e -> e.getMessage().equals("Hello"));
}
}
Understanding Spring Boot Test Annotations is essential for writing reliable and maintainable tests.
@SpringBootTest for full application tests@WebMvcTest for controller testing@DataJpaTest for repository/database tests@MockBean and Mockito for isolated unit tests@AutoConfigureMockMvc for realistic web layer testingBy combining these annotations effectively, you can build a robust test suite that ensures your application works correctly, reduces bugs, and speeds up development.