Kollaborateure mocken
Ein Bean im Kontext mit @MockitoBean durch einen Mockito-Mock ersetzen, damit ein Slice-Test fokussiert bleibt.
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
Slice tests work because you can replace the parts you're not testing with stand-ins
you control. A mock is a fake object you program to return whatever a test needs -
and Spring has two flavors: plain Mockito mocks for objects, and @MockitoBean for
swapping a bean inside the application context.
Plain Mockito - for objects you construct
When there's no Spring context (a unit test), you make a mock and pass it in yourself:
BookRepository repo = mock(BookRepository.class); // a fake
when(repo.findByIsbn("978-1")).thenReturn(Optional.of(book)); // program it
BookService service = new BookService(repo); // inject it
assertThat(service.findByIsbn("978-1")).isEqualTo(book);
verify(repo).findByIsbn("978-1"); // assert it was calledThree moves recur: create a mock, stub its responses with when(...).thenReturn(...),
and optionally verify it was called with verify(...).
@MockitoBean - for beans in the context
Inside a slice or @SpringBootTest, the object you want to fake is a bean Spring
created. @MockitoBean replaces that bean in the context with a Mockito mock:
@WebMvcTest(BookController.class)
class BookControllerWebTest {
@Autowired MockMvc mvc;
@MockitoBean BookService service; // the real BookService bean is replaced by a mock
@Test
void listsBooks() throws Exception {
when(service.findAll(null)).thenReturn(List.of(new Book("978-1", "T", "A", 1)));
mvc.perform(get("/api/books")).andExpect(jsonPath("$.length()").value(1));
}
}The controller under test is wired to your mock instead of the real service, so the test stays in the web layer.
@MockitoBean replaced @MockBean
In current Spring Boot, @MockitoBean (and @MockitoSpyBean) are the annotations for
putting Mockito mocks/spies into the test context. If you see @MockBean in older
tutorials, it's the deprecated predecessor - use @MockitoBean in new code.
A film uses a stunt double for the dangerous shots: same role, controlled behavior, so the production stays safe and predictable. A mock is a stunt double for a collaborator - it plays the part exactly as your test scripts it (return this, throw that), so the object you're really testing performs against a known, controlled partner instead of the unpredictable real thing.
For each test, say whether you'd use a plain Mockito mock(...) or @MockitoBean:
- A plain unit test of
BookService, constructed withnewand given a fake repository. - A
@WebMvcTestofBookControllerthat needs a fakeBookServicein the context.
What does @MockitoBean do in a Spring test?
Key takeaways
- A mock is a fake collaborator you program: create it, stub responses with when(...).thenReturn(...), and optionally verify(...) calls.
- Use plain Mockito mock(...) in unit tests where you construct the object yourself.
- Use @MockitoBean to replace a bean inside a Spring test context (slice or @SpringBootTest).
- @MockitoBean (and @MockitoSpyBean) are the current annotations; @MockBean is the deprecated predecessor.
- Mocking the layers you're not testing keeps each test focused and its failures meaningful.