@SpringBootTest vs @WebMvcTest: Key Differences and Usage
@SpringBootTest loads the full Spring application context for integration testing, while @WebMvcTest loads only the web layer for focused controller testing. Use @SpringBootTest for end-to-end tests and @WebMvcTest for fast, slice tests of MVC controllers.Quick Comparison
This table summarizes the main differences between @SpringBootTest and @WebMvcTest.
| Aspect | @SpringBootTest | @WebMvcTest |
|---|---|---|
| Scope | Loads full application context | Loads only web layer (controllers, MVC components) |
| Test Type | Integration test | Slice test (focused unit test) |
| Speed | Slower due to full context | Faster, lightweight context |
| Use Case | End-to-end flow and service integration | Controller logic and web layer behavior |
| Auto-configured Beans | All beans loaded | Only MVC-related beans loaded |
| Mocking | Usually real beans, can mock manually | Auto-configures MockMvc and mocks service beans |
Key Differences
@SpringBootTest boots up the entire Spring application context, including all beans, configurations, and embedded servers if needed. This makes it suitable for integration tests that verify how different parts of the app work together, such as controllers, services, repositories, and database access.
In contrast, @WebMvcTest slices the application context to load only the web layer components like controllers, filters, and MVC configurations. It excludes service and repository beans unless explicitly mocked. This makes tests faster and focused on web layer behavior, such as request handling, validation, and response formatting.
While @SpringBootTest is heavier and slower, it provides a realistic environment for full-stack testing. @WebMvcTest is lightweight and ideal for unit testing controllers without starting the full application or database.
Code Comparison
Example of a test using @SpringBootTest to test a controller with full context.
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.ResponseEntity; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class GreetingControllerSpringBootTest { @Autowired private TestRestTemplate restTemplate; @Test public void testGreeting() { ResponseEntity<String> response = restTemplate.getForEntity("/greeting", String.class); assert(response.getBody().contains("Hello")); } }
@WebMvcTest Equivalent
Equivalent test using @WebMvcTest to test the same controller with mocked dependencies.
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.web.servlet.MockMvc; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(GreetingController.class) public class GreetingControllerWebMvcTest { @Autowired private MockMvc mockMvc; @MockBean private GreetingService greetingService; // Mock service dependency @Test public void testGreeting() throws Exception { // Mock service behavior org.mockito.Mockito.when(greetingService.greet()).thenReturn("Hello from mock"); mockMvc.perform(get("/greeting")) .andExpect(status().isOk()) .andExpect(content().string("Hello from mock")); } }
When to Use Which
Choose @SpringBootTest when you want to test the full application behavior including service layers, repositories, and real integrations. It is best for end-to-end integration tests that verify the entire stack works together.
Choose @WebMvcTest when you want fast, focused tests of your web layer, especially controllers, without loading the full context or database. It is ideal for unit testing controller logic and HTTP request/response handling.
Key Takeaways
@SpringBootTest loads the full app context for integration tests.@WebMvcTest loads only the web layer for fast, focused controller tests.@SpringBootTest for end-to-end flow and real bean interactions.@WebMvcTest for isolated controller logic and HTTP behavior.@WebMvcTest to keep tests lightweight.