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. This is 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. It's 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. For example, 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.