@SpringBootTest vs @WebMvcTest in Spring Boot

When diving into the world of Spring Boot, developers often encounter a myriad of annotations that aid in the testing process. Two of the most prominent annotations are @SpringBootTest and @WebMvcTest. Both play crucial roles in ensuring the robustness of your application, but they serve different purposes. In this guide, we'll delve deep into the intricacies of these annotations, shedding light on their functionalities and differences.

graph TD A["@SpringBootTest"] B["@WebMvcTest"] C[Web Layer] D[Service Layer] E[Data Layer] A --> C A --> D A --> E B --> C

Understanding @SpringBootTest

What is @SpringBootTest?

@SpringBootTest is a versatile annotation that instructs Spring Framework to scan your application across all layers - Web, Service, and Data. Starting from the root package, the framework initiates an examination of your application classes. Consequently, beans are formulated from classes adorned with annotations like @Component, @Repository, @Service, and @Controller, and these are subsequently added to the application context.

Key Features of @SpringBootTest

  • Holistic Approach: This annotation bootstraps the entire application environment. It facilitates the @Autowire of every bean identified during component scanning into our test.
  • Integration Testing: Post the initiation of the embedded server and the creation of a web environment, @SpringBootTest empowers @Test methods to perform comprehensive integration testing.
  • Broad Perspective: It offers a panoramic view of the application, encompassing all beans, configurations, and auto-configurations that the application loads.

Diving into @WebMvcTest

What is @WebMvcTest?

@WebMvcTest is a specialized annotation tailored for the web layer of your application. Its primary function is to test the controller layer, encompassing request mappings, JSON serialization/deserialization, and other web-centric components.

Key Features of @WebMvcTest

  • Selective Scanning: This annotation instructs the Spring Framework to exclusively scan classes associated with the MVC infrastructure, such as @Controller, @ControllerAdvice, @JsonComponent, WebMvcConfigurer, and HandlerMethodArgumentResolver. Classes with @Component, @Service, or @Repository annotations are bypassed.
  • Controller Specificity: You can pinpoint specific controllers for scanning using @WebMvcTest. In such cases, only the designated controllers are examined.
Java
@WebMvcTest(controllers = YourController.class)
class YourControllerTest {}

Contrasting @SpringBootTest and @WebMvcTest

While both annotations are instrumental in testing, their scope and depth vary:

  • Depth of Integration Testing: @SpringBootTest loads the complete application context, encompassing database, security, and other infrastructural components, making it apt for integration testing. In contrast, @WebMvcTest is tailored for unit testing the controller layer, as it solely loads the web layer and simulates the other layers.
  • Configuration Overhead: @SpringBootTest demands more configuration due to its comprehensive nature. This might necessitate additional configurations for testing, such as database and security setups. Conversely, @WebMvcTest is lighter, focusing only on the web layer, thus reducing the need for extensive configurations.

Practical Demonstrations

Testing with @SpringBootTest

For a holistic testing approach, encompassing the web, service, and database layers, @SpringBootTest is the go-to annotation. Here's a practical demonstration:

Java
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyApplicationTests {
    @Autowired
    private MyService myService;
    @Autowired
    private MyRepository myRepository;
    @Autowired
    private WebApplicationContext context;
    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
    }

    @Test
    public void testCreateUser() throws Exception {
        // Test logic here
    }
}

Testing with @WebMvcTest

For a focused approach on the web layer, especially the controller layer, @WebMvcTest is the ideal choice. Here's a practical demonstration:

Java
@RunWith(SpringRunner.class)
@WebMvcTest(MyController.class)
public class MyControllerTests {
    @Autowired
    private MockMvc mockMvc;
    @MockBean
    private MyService myService;

    @Test
    public void testGetUser() throws Exception {
        // Test logic here
    }
}

Conclusion

In the realm of Spring Boot, both @SpringBootTest and @WebMvcTest are invaluable tools. While @SpringBootTest provides a comprehensive testing landscape, @WebMvcTest offers a focused approach. Depending on your testing requirements, you can leverage the unique strengths of each annotation to ensure the resilience and robustness of your application.

Author