0
0
SpringbootHow-ToBeginner · 3 min read

How to Use @WebMvcTest in Spring Boot for Controller Testing

Use @WebMvcTest in Spring Boot to test only the web layer (controllers) without starting the full application context. It loads only the MVC components needed for controller tests, making tests faster and more focused.
📐

Syntax

The @WebMvcTest annotation is placed on a test class to load only Spring MVC components such as controllers, filters, and related configurations. You specify the controller class to test as a parameter.

It disables full auto-configuration and limits the context to web layer beans only.

java
@WebMvcTest(YourController.class)
public class YourControllerTest {
    @Autowired
    private MockMvc mockMvc;

    // test methods here
}
💻

Example

This example shows how to test a simple Spring Boot controller using @WebMvcTest. It verifies that a GET request to /hello returns the expected response.

java
package com.example.demo;

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.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest(HelloController.class)
public class HelloControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testHello() throws Exception {
        mockMvc.perform(get("/hello"))
               .andExpect(status().isOk())
               .andExpect(content().string("Hello, Spring Boot!"));
    }
}

// Controller class
package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello, Spring Boot!";
    }
}
Output
Test passes with HTTP 200 OK and response body "Hello, Spring Boot!"
⚠️

Common Pitfalls

  • Not specifying the controller class in @WebMvcTest can load multiple controllers, making tests slower.
  • Trying to load service or repository beans will fail because @WebMvcTest only loads web layer beans.
  • For dependencies like services, use @MockBean to mock them in the test.
java
/* Wrong: Missing @MockBean for service dependency causes failure */
@WebMvcTest(UserController.class)
public class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    // UserService is not mocked, test will fail
}

/* Right: Mock service dependency */
@WebMvcTest(UserController.class)
public class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserService userService;

    // Now test can run with mocked service
}
📊

Quick Reference

  • @WebMvcTest(Controller.class): Loads only the specified controller and MVC components.
  • MockMvc: Used to perform HTTP requests in tests.
  • @MockBean: Mock dependencies like services for isolated controller tests.
  • Does not load full Spring context or database layers.

Key Takeaways

Use @WebMvcTest to test only Spring MVC controllers without loading full context.
Specify the controller class in @WebMvcTest to limit loaded beans and speed up tests.
Mock service or repository dependencies with @MockBean to avoid context loading errors.
Use MockMvc to simulate HTTP requests and verify controller responses.
Avoid loading full application context for faster, focused web layer tests.