What is the difference between @SpringBootTest and @WebMvcTest?
Both @SpringBootTest and @WebMvcTest are Spring Boot testing annotations, but they are designed for different testing scopes and purposes. Understanding their distinctions is crucial for writing efficient and targeted tests.
@SpringBootTest
@SpringBootTest is a comprehensive integration testing annotation provided by Spring Boot. It loads the entire Spring application context, essentially starting a full application (or a significant portion of it) for testing. It can start a real embedded server (like Tomcat or Netty) or a mock environment, depending on the 'webEnvironment' attribute.
When using @SpringBootTest, all beans, controllers, services, repositories, and configurations are loaded. This makes it suitable for end-to-end integration tests where you want to verify the entire application flow, from request handling down to database interactions (if a real database or an in-memory database is configured). It’s also often used in conjunction with @TestPropertySource, @ActiveProfiles, and various Spring Boot testing utilities.
@WebMvcTest
@WebMvcTest is a more focused, slice-based testing annotation. It is specifically designed for testing the web layer (MVC controllers) of a Spring Boot application. It auto-configures Spring MVC components required for testing controllers, such as MockMvc, Argument Resolvers, Message Converters, and filters, but it does *not* load the entire application context.
Crucially, @WebMvcTest scans for @Controller, @ControllerAdvice, @JsonComponent, and WebMvcConfigurer beans, but it excludes other types of beans like @Service, @Component, @Repository. This means you typically need to mock any dependent services or repositories that your controller relies on. It focuses on the mapping of requests, input validation, and response serialization within the controller layer without the overhead of loading business logic or data access layers.
Key Differences
- Scope: @SpringBootTest loads the entire application context, while @WebMvcTest focuses only on the web layer.
- Auto-configuration: @SpringBootTest auto-configures everything discoverable. @WebMvcTest auto-configures only Spring MVC infrastructure.
- Beans Loaded: @SpringBootTest loads all beans (@Controller, @Service, @Repository, etc.). @WebMvcTest loads only web-related components (@Controller, @ControllerAdvice, etc.), excluding business and data access layers.
- Dependencies: With @WebMvcTest, you often need to mock services and repositories that your controller depends on using @MockBean. @SpringBootTest typically uses the actual injected beans (unless explicitly mocked).
- Speed: Tests using @WebMvcTest are generally faster because they load a much smaller portion of the application context. @SpringBootTest tests are slower due to the full context loading.
- Use Case: @SpringBootTest is for end-to-end integration tests. @WebMvcTest is for unit/integration tests specifically for the web layer (controllers).
When to Use Which
Use @SpringBootTest when: You need to test the entire application flow, including interactions between controllers, services, repositories, and potentially a database. This is ideal for verifying that all layers work together correctly in an integrated environment. It's suitable for higher-level integration or end-to-end tests.
Use @WebMvcTest when: You want to test only the web layer of your application. This includes verifying controller mappings, request parameter binding, input validation, JSON serialization/deserialization, and HTTP response handling, isolated from the business logic and data access layers. It promotes faster, more focused tests for your controllers.