In Controller Layer Unit Testing
No Tomcat, no DB, no real API calls — just a simulated web environment.
@WebMvcTest
When you annotate your test class with it, Spring Boot:
✅ Loads only the web layer (Controllers, Filters, Exception Handlers, etc.).
✅ Does not load services, repositories, or databases.
✅ Automatically configures a MockMvc instance.
MockMvc
MockMvc is a powerful Spring test utility that simulates HTTP calls to your controller without starting an actual server.
[Test Code] → [MockMvc] → [Controller] → (Mocked Service)
So your test “sends” a fake HTTP GET or POST request, and MockMvc passes it through the Spring MVC stack to your controller.
Sample
@WebMvcTest(OrderController.class)
class OrderControllerTest {
@Autowired
private MockMvc mockMvc; // simulates HTTP calls
@MockBean
private OrderService orderService; // replaces the real service
@Test
void getOrder_returnsOrderDetails() throws Exception {
// Arrange
when(orderService.findById(1L))
.thenReturn(new Order(1L, "Shoes", 2));
// Act & Assert
mockMvc.perform(get("/orders/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("Shoes"));
} }@MockBean
Your controller depends on other layers — usually a service. Now — when you test this controller using @WebMvcTest, Spring Boot loads only the web layer (controllers, filters, exception handlers, etc.).It does not load your Service or Repository beans, because that would pull in the entire application context (making the test heavy and slow). @MockBean tells Spring Boot: “Create a fake version (mock) of this dependency and register it in the Spring context.”
when(orderService.findById(1L)).thenReturn(new Order(1L, “Shoes”, 2));
“Whenever the controller calls orderService.findById(1L), return this fake Order.”
@Mock vs @MockBean
Creates Mockito mock | ✅ | ✅
Injects into Spring context ❌ | ✅
Works with @Autowired beans| ❌ ✅
Replaces existing Spring beans | ❌ | ✅
So @MockBean integrates Mockito with Spring’s DI container.That’s why it’s used in Spring Boot tests — it “plugs” the mock into the real dependency injection graph.
Feature | @Mock | @MockBean |
MockMvc without HTTP
MockMvc builds a mock HttpServletRequest and passes it directly to the DispatcherServlet. The DispatcherServlet routes the request through: Interceptors, Controller, Exception resolvers, Message converters just as it would in a real app.
DSL in Mock MVC
Does not have a when() method — it starts with perform(…)
mockMvc.perform(get(“/api/products/1”)) - accepts a RequestBuilder (like get(), post(), put()).
andExpect() — Verify the Result
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath(“$.price”).value(999.0)); andReturn() gives you the full MvcResult object, allowing you to manually inspect the result:
@MockBean and the Mockito DSL
when(productService.getProduct(1L))
.thenReturn(new Product(1L, “Laptop”, 999.0));