Start Learning
Javaneer
Back to stage
Module 5·Testing Spring Applications

Mocking Collaborators

Replace a bean in the context with a Mockito mock using @MockitoBean, so a slice test stays focused.

14 min readIntermediate
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 called

Three 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 stunt double stands in for the risky scene

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.

Mock or @MockitoBean?

For each test, say whether you'd use a plain Mockito mock(...) or @MockitoBean:

  1. A plain unit test of BookService, constructed with new and given a fake repository.
  2. A @WebMvcTest of BookController that needs a fake BookService in 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.
Was this lesson helpful?
Edit this page on GitHub