Spring Boot Testing Guide
Testing Annotations Comparison
Section titled “Testing Annotations Comparison”| Feature | @SpringBootTest |
@WebMvcTest |
@DataJpaTest |
|---|---|---|---|
| Purpose | Full integration test | Test only web layer | Test only JPA layer |
| Context Loaded | Entire Spring Boot context | Only MVC components | Only JPA components |
| Speed | Slow | Fast | Fast |
| Beans Loaded | All beans | Controllers, MVC config | Repositories, EntityManager |
| DB Access | Yes | No | Yes |
| Use Case | End-to-end testing | Controller testing | Repository testing |
@SpringBootTest
Section titled “@SpringBootTest”Loads the entire Spring Boot application context and is used for integration testing across multiple layers.
@SpringBootTestclass OrderServiceTest {
@Autowired private OrderService orderService;
@Test void testCreateOrder() { Order order = orderService.createOrder(); assertNotNull(order); }}Use cases
- End-to-end tests
- Integration tests
- Multiple-layer interaction
@WebMvcTest
Section titled “@WebMvcTest”Loads only the web layer.
Included:
- Controllers
@ControllerAdvice- Filters
WebMvcConfigurer
Excluded:
- Services
- Repositories
- Database configuration
@WebMvcTest(ProductController.class)class ProductControllerTest {
@Autowired private MockMvc mockMvc;
@MockBean private ProductService productService;
@Test void testGetProducts() throws Exception {
when(productService.getProducts()).thenReturn(List.of());
mockMvc.perform(get("/products")) .andExpect(status().isOk()); }}@DataJpaTest
Section titled “@DataJpaTest”Loads only the persistence layer.
Included:
- Repositories
- EntityManager
- Hibernate
- JPA configuration
Uses an embedded H2 database by default.
@DataJpaTestclass ProductRepositoryTest {
@Autowired private ProductRepository repository;
@Test void testSave() {
Product p = new Product("Laptop");
repository.save(p);
assertNotNull(p.getId()); }}Test Slice Annotations
Section titled “Test Slice Annotations”Test slice annotations load only a focused part of the application context, making tests faster.
| Annotation | Layer |
|---|---|
@WebMvcTest |
Web |
@DataJpaTest |
JPA |
@JdbcTest |
JDBC |
@JsonTest |
JSON serialization |
@RestClientTest |
REST clients |
Testing REST Controllers
Section titled “Testing REST Controllers”Use MockMvc together with @WebMvcTest.
@RestController@RequestMapping("/products")class ProductController {
@GetMapping public List<Product> getProducts() { return List.of(new Product("Laptop")); }}@WebMvcTest(ProductController.class)class ProductControllerTest {
@Autowired private MockMvc mockMvc;
@Test void testGetProducts() throws Exception {
mockMvc.perform(get("/products")) .andExpect(status().isOk()) .andExpect(jsonPath("$[0].name").value("Laptop")); }}Mocking Dependencies
Section titled “Mocking Dependencies”Use @MockBean to replace Spring-managed beans with Mockito mocks.
@WebMvcTest(ProductController.class)class ProductControllerTest {
@MockBean private ProductService productService;
}when(productService.getProducts()) .thenReturn(List.of(new Product("Phone")));| Annotation | Purpose |
|---|---|
@Mock |
Pure Mockito |
@MockBean |
Mockito mock registered as a Spring bean |
Kafka and RabbitMQ Integration Testing
Section titled “Kafka and RabbitMQ Integration Testing”Embedded Kafka
Section titled “Embedded Kafka”@EmbeddedKafka(partitions = 1, topics = {"orders"})@SpringBootTestclass KafkaIntegrationTest {
@Autowired private KafkaTemplate<String, String> kafkaTemplate;
@Test void testKafkaProducer() {
kafkaTemplate.send("orders", "test message"); }}Dependency:
spring-kafka-testTestcontainers (Recommended)
Section titled “Testcontainers (Recommended)”@Testcontainers@SpringBootTestclass KafkaTest {
@Container static KafkaContainer kafka = new KafkaContainer("confluentinc/cp-kafka:7.3.0");
}Advantages:
- Real Kafka broker
- Production-like environment
Integration Tests with Embedded Databases
Section titled “Integration Tests with Embedded Databases”Add H2 for tests:
testImplementation 'com.h2database:h2'Example:
@SpringBootTest@AutoConfigureTestDatabaseclass OrderRepositoryTest {
@Autowired private OrderRepository repository;
@Test void testSaveOrder() {
Order order = new Order();
repository.save(order);
assertNotNull(order.getId()); }}Spring Boot Test Database Flow
Section titled “Spring Boot Test Database Flow”flowchart TD
A[Test Context Starts] --> B[Detect H2]
B --> C[Create In-Memory Database]
C --> D[Run Hibernate DDL / schema.sql]
D --> E[Execute Tests]
E --> F[Rollback Transaction]
Interview Tip
Section titled “Interview Tip”Why prefer @WebMvcTest over @SpringBootTest for controller tests?
@SpringBootTestloads the full application context and is slower.@WebMvcTestloads only the MVC layer, making tests faster and more focused.- It is the preferred choice for isolated REST controller testing.
Key Takeaways
Section titled “Key Takeaways”- Use
@SpringBootTestfor full integration testing. - Use
@WebMvcTestfor REST controller tests withMockMvc. - Use
@DataJpaTestfor repository and persistence testing. - Use
@MockBeanto mock Spring-managed dependencies. - Prefer Testcontainers for realistic Kafka integration testing.
- Embedded H2 databases make repository integration tests fast and isolated.