Spring Boot @WebMvcTest Annotation Example

In Spring MVC, testing the web layer of an application is essential to ensure its functionality and behavior. The @WebMvcTest annotation is a powerful testing annotation provided by the Spring Framework that focuses specifically on testing the web layer of a Spring MVC application. 

In this blog post, we will explore the @WebMvcTest annotation, its usage, and its benefits in testing Spring MVC controllers. 

What is the @WebMvcTest Annotation?

The @WebMvcTest annotation is used to perform unit tests on Spring MVC controllers. It allows you to test the behavior of controllers, request mappings, and HTTP responses in a controlled and isolated environment. By using @WebMvcTest, you can narrow down the scope of testing to just the web layer, without loading the entire application context.

In the Spring Boot application, the @WebMvcTest annotation-based test runs faster because it will load only the specified controller and its dependencies without loading the entire application.

Spring Boot instantiates only the web layer rather than the whole application context. In an application with multiple controllers, you can even ask for only one to be instantiated by using, for example, @WebMvcTest(HelloWorldController.class).

Spring Boot @WebMvcTest Annotation Example

Add Maven Dependencies

Add the following Maven dependencies to your Spring Boot application:
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope>
</dependency>

Create Spring MVC Controller 

Next, let's create HelloWorldController and annotate it with @RestController annotation:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldController {

    @GetMapping("/hello/{name}")
    public String sayHello(@PathVariable String name) {
        return "Hello, " + name + "!";
    }
}
In the above example, the HelloWorldController class is annotated with @RestController, which indicates that it is a controller class responsible for handling HTTP requests and returning JSON responses. 

The @GetMapping annotation is used to map the /hello/{name} URL path to the sayHello method. The @PathVariable annotation is used to extract the {name} path variable and pass it as a method parameter. The method returns a simple greeting message.

Next, run your Spring boot application and send a request to the REST API. For example, you can send a GET request to http://localhost:8080/hello/Ramesh to get a response of "Hello, Ramesh!".

Unit Testing HelloController Class

Create a test class and annotate it with @WebMvcTest:

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.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;

@WebMvcTest(HelloWorldController.class)
public class HelloWorldControllerTest {

	@Autowired
	private MockMvc mockMvc;

	@Test
	public void testGetEndpoint() throws Exception {
		mockMvc.perform(get("/hello/Ramesh"))
				.andDo(print())
				.andExpect(status().isOk())
				.andExpect(content().string("Hello, Ramesh!"));
	}
}
Note that we are using @WebMvcTest annotation to load only HelloWorldController class:
@WebMvcTest(HelloWorldController.class)
The MockMvc instance is autowired and used to perform HTTP requests and assertions in the test methods.
	@Autowired
	private MockMvc mockMvc;

Run the Unit Test


Benefits of @WebMvcTest Annotation

Faster Test Execution: With @WebMvcTest, only the necessary components for testing the web layer are loaded, resulting in faster test execution compared to loading the entire application context. 

Isolated Testing: @WebMvcTest focuses solely on the web layer, isolating it from other components, such as services, repositories, and external dependencies. This allows for more focused and targeted tests.

Simulated HTTP Requests: The MockMvc instance provided by @WebMvcTest allows you to simulate HTTP requests and validate the responses in a controlled manner. You can perform assertions on the status codes, headers, response bodies, and more. 

Annotation-Based Configuration: @WebMvcTest leverages the annotation-based configuration of Spring MVC, allowing you to define test cases using intuitive and concise annotations. 

Simplified Setup: @WebMvcTest automatically configures the necessary components, such as the Spring MVC infrastructure, message converters, and view resolvers, for testing the web layer. This reduces the setup effort required for testing.
Unit Testing CRUD

Conclusion

The @WebMvcTest annotation is a valuable tool for testing the web layer of a Spring MVC application. By focusing on the controllers and their interactions with HTTP requests and responses, 

@WebMvcTest allows for efficient and targeted testing. It provides a simplified testing setup, faster test execution, and the ability to validate the behavior of Spring MVC controllers in a controlled environment.

With @WebMvcTest, you can ensure the correctness and robustness of your web applications built on Spring MVC.

What's Next?

Check out the complete tutorial on unit testing CRUD REST APIs using JUnit, Mockito, @WebMvcTest annotation, and MockMvc: Spring Boot Unit Testing CRUD REST API with JUnit and Mockito

Comments