Bird
Raised Fist0
JUnittesting~7 mins

@WebMvcTest for controller testing in JUnit

Choose your learning style10 modes available
Introduction

@WebMvcTest helps test only the web layer of your application, like controllers, without starting the full app. It makes tests faster and focused.

When you want to check if your controller handles HTTP requests correctly.
When you want to test controller methods without loading services or repositories.
When you want to verify the HTTP status and response content from your controller.
When you want to test controller behavior with mock dependencies.
When you want to isolate controller tests from other layers for faster feedback.
Syntax
JUnit
@WebMvcTest(ControllerClass.class)
public class ControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private SomeService someService;

    @Test
    public void testControllerMethod() throws Exception {
        mockMvc.perform(get("/endpoint"))
               .andExpect(status().isOk())
               .andExpect(content().string("expected response"));
    }
}

@WebMvcTest loads only the controller and related MVC components, not the full Spring context.

Use @MockBean to provide mock implementations for service dependencies.

Examples
Simple test for a controller that returns "Hello World" on /hello endpoint.
JUnit
@WebMvcTest(HelloController.class)
public class HelloControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void shouldReturnHello() throws Exception {
        mockMvc.perform(get("/hello"))
               .andExpect(status().isOk())
               .andExpect(content().string("Hello World"));
    }
}
Test with a mocked service to control the response returned by the controller.
JUnit
@WebMvcTest(UserController.class)
public class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserService userService;

    @Test
    public void shouldReturnUserName() throws Exception {
        when(userService.getUserName()).thenReturn("Alice");

        mockMvc.perform(get("/username"))
               .andExpect(status().isOk())
               .andExpect(content().string("Alice"));
    }
}
Sample Program

This test checks the /greet endpoint of GreetingController. The GreetingService is mocked to return "Hello Test". The test verifies the HTTP status is 200 OK and the response body matches the mocked string.

JUnit
package com.example.demo;

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;
import static org.mockito.Mockito.when;

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;

@WebMvcTest(GreetingController.class)
public class GreetingControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private GreetingService greetingService;

    @Test
    public void testGreeting() throws Exception {
        when(greetingService.greet()).thenReturn("Hello Test");

        mockMvc.perform(get("/greet"))
               .andExpect(status().isOk())
               .andExpect(content().string("Hello Test"));
    }
}

// Controller class
package com.example.demo;

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

@RestController
public class GreetingController {

    private final GreetingService greetingService;

    public GreetingController(GreetingService greetingService) {
        this.greetingService = greetingService;
    }

    @GetMapping("/greet")
    public String greet() {
        return greetingService.greet();
    }
}

// Service interface
package com.example.demo;

public interface GreetingService {
    String greet();
}
OutputSuccess
Important Notes

Always mock service dependencies to keep controller tests isolated.

Use MockMvc to simulate HTTP requests and check responses without starting a server.

@WebMvcTest does not load security or database layers unless explicitly configured.

Summary

@WebMvcTest focuses on testing Spring MVC controllers only.

MockMvc helps simulate HTTP calls and verify responses.

Mock dependencies with @MockBean to isolate controller logic.

Practice

(1/5)
1. What is the main purpose of using @WebMvcTest in Spring Boot testing?
easy
A. To test only the Spring MVC controllers without starting the full application context
B. To test the entire application including database and services
C. To perform integration testing of all layers
D. To mock external APIs automatically

Solution

  1. Step 1: Understand the role of @WebMvcTest

    @WebMvcTest is designed to load only the Spring MVC components, mainly controllers, for focused testing.
  2. Step 2: Compare with other test types

    Unlike full integration tests, it does not load services or repositories, making tests faster and isolated.
  3. Final Answer:

    To test only the Spring MVC controllers without starting the full application context -> Option A
  4. Quick Check:

    @WebMvcTest = Controller-only test [OK]
Hint: Remember: @WebMvcTest loads controllers only, not full app [OK]
Common Mistakes:
  • Thinking @WebMvcTest loads full application context
  • Confusing @WebMvcTest with @SpringBootTest
  • Assuming it mocks external APIs automatically
2. Which annotation is used to mock a service dependency inside a @WebMvcTest annotated test class?
easy
A. @InjectMocks
B. @MockMvc
C. @Autowired
D. @MockBean

Solution

  1. Step 1: Identify mocking annotation for Spring beans

    @MockBean is used to add mock implementations of Spring beans into the application context during tests.
  2. Step 2: Differentiate from other annotations

    @MockMvc is not an annotation, @Autowired injects real beans, and @InjectMocks is from Mockito but not for Spring context injection.
  3. Final Answer:

    @MockBean -> Option D
  4. Quick Check:

    Mock dependencies in @WebMvcTest = @MockBean [OK]
Hint: Use @MockBean to mock Spring beans in @WebMvcTest [OK]
Common Mistakes:
  • Using @Autowired instead of @MockBean for mocks
  • Confusing @MockBean with Mockito's @InjectMocks
  • Thinking @MockMvc is an annotation
3. Given the following test snippet using @WebMvcTest and MockMvc:
@WebMvcTest(MyController.class)
class MyControllerTest {
  @Autowired
  private MockMvc mockMvc;

  @Test
  void testHello() throws Exception {
    mockMvc.perform(get("/hello"))
      .andExpect(status().isOk())
      .andExpect(content().string("Hello World"));
  }
}
What will happen if the controller method mapped to /hello returns "Hello World" as response?
medium
A. The test will fail because MockMvc is not autowired correctly
B. The test will pass because the response matches the expected string
C. The test will fail due to status code mismatch
D. The test will throw a NullPointerException

Solution

  1. Step 1: Analyze the test expectations

    The test expects HTTP status 200 OK and response body "Hello World".
  2. Step 2: Match with controller behavior

    If the controller returns "Hello World" with status 200, both expectations are met, so the test passes.
  3. Final Answer:

    The test will pass because the response matches the expected string -> Option B
  4. Quick Check:

    Matching response and status = test pass [OK]
Hint: Match expected status and content to pass MockMvc tests [OK]
Common Mistakes:
  • Assuming test fails if no explicit status set in controller
  • Confusing autowiring issues with test failures
  • Ignoring response content in assertions
4. Consider this test class snippet:
@WebMvcTest(MyController.class)
class MyControllerTest {
  @Autowired
  private MockMvc mockMvc;

  @MockBean
  private MyService myService;

  @Test
  void testEndpoint() throws Exception {
    when(myService.getData()).thenReturn("data");
    mockMvc.perform(get("/data"))
      .andExpect(status().isOk())
      .andExpect(content().string("data"));
  }
}
If the test fails with a 404 Not Found error, what is the most likely cause?
medium
A. The test class is missing @SpringBootTest annotation
B. The mock service is not returning the expected value
C. The controller method for /data is missing or not mapped correctly
D. MockMvc is not autowired properly

Solution

  1. Step 1: Understand 404 error in MockMvc test

    A 404 means the requested URL is not found in the controller mappings.
  2. Step 2: Check test setup

    @WebMvcTest loads only controllers; if /data mapping is missing or incorrect, 404 occurs despite mocks.
  3. Final Answer:

    The controller method for /data is missing or not mapped correctly -> Option C
  4. Quick Check:

    404 error = missing controller mapping [OK]
Hint: 404 in @WebMvcTest usually means missing controller mapping [OK]
Common Mistakes:
  • Blaming mock service return value for 404
  • Assuming @SpringBootTest is needed for controller tests
  • Ignoring URL mapping correctness
5. You want to test a controller method that depends on a service returning a list of users. Using @WebMvcTest, how should you mock the service and verify the controller returns JSON with the user list correctly?
hard
A. Use @MockBean to mock the service, stub the method to return a list, then use MockMvc to perform GET and expect JSON content
B. Use @Autowired to inject the real service and call the controller method directly
C. Use @SpringBootTest to load full context and test the controller with real service
D. Use Mockito's @InjectMocks on the controller and call methods without MockMvc

Solution

  1. Step 1: Mock the service dependency with @MockBean

    In @WebMvcTest, use @MockBean to replace the service bean with a mock and stub its method to return the user list.
  2. Step 2: Use MockMvc to perform HTTP GET and verify JSON response

    Perform a GET request on the controller endpoint and assert the JSON response matches the expected user list.
  3. Final Answer:

    Use @MockBean to mock the service, stub the method to return a list, then use MockMvc to perform GET and expect JSON content -> Option A
  4. Quick Check:

    Mock service + MockMvc GET + JSON assert = correct test [OK]
Hint: Mock service with @MockBean and verify JSON via MockMvc [OK]
Common Mistakes:
  • Injecting real service instead of mocking
  • Using full context test instead of @WebMvcTest
  • Calling controller methods directly without MockMvc
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard