What is the difference between @MockBean (or @MockitoBean) and Mockito's plain mock()?
Quick Answer
Mockito's plain mock(SomeType.class) creates a mock object entirely outside of Spring — useful in a pure unit test that constructs the class under test directly with new, with no Spring context involved at all. @MockitoBean (the modern replacement for the deprecated @MockBean) creates a Mockito mock and additionally registers it as a bean inside the Spring test ApplicationContext, replacing whatever real bean of that type would otherwise have been wired in — necessary whenever the class under test is itself resolved and injected by Spring (e.g., inside a @WebMvcTest or @SpringBootTest) rather than constructed directly by the test.
Detailed Answer
Both ultimately create a Mockito mock object, but they differ in whether that mock is registered inside a Spring ApplicationContext:
Plain Mockito.mock(SomeType.class) creates a mock with no Spring involvement whatsoever — appropriate for a pure, Spring-free unit test where you construct the class under test directly:
@Test
void placesOrderSuccessfully() {
PaymentGateway mockGateway = mock(PaymentGateway.class); // plain Mockito, no Spring context at all
when(mockGateway.charge(any(), any())).thenReturn(true);
OrderService service = new OrderService(mockGateway); // constructed directly, not via Spring
assertTrue(service.placeOrder(new Order(...)));
}
This is the fastest possible test — no ApplicationContext loads at all — and is exactly the kind of test constructor injection is specifically designed to make easy (see the constructor-injection question).
@MockitoBean (the current annotation; @MockBean served the same purpose in older Spring Boot versions and is now deprecated in favor of it) is used inside a Spring test context — it creates a Mockito mock and registers it as a bean in the test's ApplicationContext, replacing whatever real bean of that type would otherwise have been created/wired there:
@WebMvcTest(OrderController.class)
class OrderControllerTest {
@Autowired MockMvc mockMvc;
@MockitoBean
OrderService orderService; // Spring wires this mock into OrderController instead of a real OrderService
@Test
void ...() throws Exception {
when(orderService.getOrder(1L)).thenReturn(new Order(1L, "PENDING"));
mockMvc.perform(get("/orders/1")).andExpect(status().isOk());
}
}
When you need @MockitoBean instead of plain mock(): whenever the class under test is itself resolved and injected by Spring rather than constructed directly by your test code — e.g., testing a controller via MockMvc inside a @WebMvcTest, where OrderController is instantiated by the Spring test context and needs its OrderService dependency supplied through that same context, not through a constructor call your test code controls directly.
Rule of thumb: default to plain Mockito.mock() plus direct object construction wherever possible (it's simpler and faster); reach for @MockitoBean specifically when the object under test is managed by a Spring test context and you need to replace one of its dependencies within that context.