Testing REST APIs with MockMvc
You need to test your REST API endpoints to make sure they return the right HTTP status codes and JSON. But starting a real Tomcat server for every test is slow. <strong>MockMvc</strong> allows you to test the web layer without starting a real server.
The Flight Simulator Analogy:
When training pilots in Hyderabad, they don't put a student in a real ₹100 crore Airbus on the first day. They put them in a flight simulator. The simulator mimics the controls, the weather, and the dashboard perfectly, but the plane never leaves the ground.
MockMvc is a flight simulator for your Spring Boot app. It fakes HTTP requests (GET, POST) and sends them to your controllers. The controller runs, but Tomcat never actually starts. This makes your web tests incredibly fast.
- @WebMvcTest: A specialized test annotation that boots only the web layer (Controllers, JSON converters). It does NOT boot your Services or Repositories.
- @MockBean: Because
@WebMvcTestdoesn't boot the Service layer, you must create a fake (mock) Service bean for the Controller to talk to. - MockMvc: The object used to build and execute fake HTTP requests and assert the responses.
- @AutoConfigureMockMvc: Automatically configures the MockMvc instance.
package com.devinhyderabad;
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;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
// 1. Boot only the BookController (Web Layer)
@WebMvcTest(BookController.class)
public class BookControllerTest {
@Autowired
private MockMvc mockMvc; // The flight simulator
// 2. Fake the Service layer (since @WebMvcTest doesn't load it)
@MockBean
private BookService bookService;
@Test
public void testGetBookById_ReturnsJsonAnd200() throws Exception {
// 3. Arrange: Train the mock service
Book mockBook = new Book(1L, "MockMvc Guide", "Deva");
when(bookService.getBookById(1L)).thenReturn(mockBook);
// 4. Act & Assert: Perform a fake GET request and check the response
mockMvc.perform(get("/api/books/1"))
.andExpect(status().isOk()) // Expect HTTP 200
.andExpect(jsonPath("$.title").value("MockMvc Guide")); // Expect JSON field
}
}Interview Question: "What is the difference between @SpringBootTest and @WebMvcTest?"
Answer: @SpringBootTest loads the entire application context (Controllers, Services, Repositories, DB). It is slow but tests everything. @WebMvcTest loads only the web layer (the specified Controller). It does not load the database or services. It is extremely fast and is used specifically for testing HTTP request/response mapping, status codes, and JSON serialization.
Enterprise Note: MockMvc is perfect for testing 400 Bad Request validation errors. You can send a faulty JSON payload to your endpoint and assert that Spring returns a 400 status, ensuring your @Valid annotations are working correctly without needing a database.
Key Takeaways
- ✅ @WebMvcTest boots only the web layer (Controllers) — no full Spring context
- ✅ @MockBean is used to fake the Service layer in @WebMvcTest
- ✅ MockMvc performs fake HTTP requests and asserts responses without starting Tomcat
- ✅ MockMvc is ideal for testing @Valid validation errors (400 Bad Request)
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login