Mocking Collaborators
Replace a bean in the context with a Mockito mock using @MockitoBean, so a slice test stays focused.
On this page
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.