Loslegen
Javaneer
Zurück zur Stufe
Modul 5·Spring-Anwendungen testen

Web-Slice-Tests mit @WebMvcTest

Controller isoliert mit MockMvc testen - Routing, Validierung, Statuscodes und JSON - ohne Datenbank.

16 Min. LesezeitFortgeschritten

Deutsche Übersetzung in Arbeit

Diese Lektion ist noch nicht ins Deutsche übersetzt und wird daher auf Englisch angezeigt. Der Rest der Seite ist vollständig lokalisiert.

Auf dieser Seite

To test a controller you don't need a database, a real service, or a running server - you need to check that a request is routed correctly, validated, and turned into the right status and JSON. @WebMvcTest loads just the web layer and gives you MockMvc to fire requests at it.

The slice

@WebMvcTest(BookController.class) starts Spring MVC and that one controller - no services, no repositories, no database. Because the controller depends on BookService, you supply a mock with @MockitoBean:

@WebMvcTest(BookController.class)
class BookControllerWebTest {

    @Autowired MockMvc mvc;              // fires simulated HTTP requests
    @MockitoBean BookService service;    // a Mockito mock, put into the context

    @Test
    void returns404WhenBookMissing() throws Exception {
        when(service.findByIsbn("000")).thenThrow(new BookNotFoundException("000"));

        mvc.perform(get("/api/books/000"))
            .andExpect(status().isNotFound())
            .andExpect(jsonPath("$.title").value("Not found"));
    }
}

MockMvc runs the request through the real MVC machinery - routing, argument binding, validation, your exception handler, JSON serialization - without a network or server.

What it's perfect for

  • Status codes — 200, 201, 404, 400.
  • Validation — POST an invalid body, expect 400 and the error details.
  • JSON shape — assert fields with jsonPath.
  • Routing & mapping — the right method handles the right URL and verb.
@Test
void rejectsInvalidNewBook() throws Exception {
    String badBody = "{\"isbn\":\"bad\",\"title\":\"\",\"author\":\"X\",\"copies\":0}";
    mvc.perform(post("/api/books").contentType(APPLICATION_JSON).content(badBody))
        .andExpect(status().isBadRequest());
}
A flight simulator for your controller

Pilots train in a flight simulator: real cockpit, real controls, real responses - but no actual aircraft, fuel, or sky. MockMvc is a flight simulator for your web layer: real routing, real validation, real JSON, but no server, network, or database. You exercise the controller under realistic conditions, fast and safely.

Mock the layer below, test the layer you're on

The point of a slice is focus. In a @WebMvcTest you @MockitoBean the service and script its responses, so a failing test points squarely at the web layer - not at service logic or a database. Test the service's logic separately, in its own test.

Test the create endpoint

Write, in words, two @WebMvcTest cases for POST /api/books: one where the service succeeds and you expect 201 Created, and one where the request body is invalid and you expect 400. What do you mock, and what do you assert in each?

In a @WebMvcTest, how is the controller's service dependency provided?

Key takeaways

  • @WebMvcTest loads only the web layer plus the target controller - no service, repository, or database.
  • MockMvc fires requests through the real MVC machinery (routing, validation, exception handling, JSON) with no server or network.
  • Supply the controller's collaborators as @MockitoBean mocks and stub them per test.
  • It's ideal for asserting status codes, validation behavior, JSON shape, and routing.
  • Keep the slice focused: test service logic in its own test, not through the controller.
War diese Lektion hilfreich?
Diese Seite auf GitHub bearbeiten