middle
Что такое MockBean и SpyBean?
@MockBean и @SpyBean — аннотации Spring Boot Test, позволяющие подменять бины в контексте Spring моками и шпионами Mockito.
MockBean
@MockBean заменяет бин в контексте полностью мок-объектом. Все методы по умолчанию возвращают null (или значение по умолчанию для примитивов). Полезно для изоляции тестируемого компонента от зависимостей:
Пример кода
@SpringBootTest
class OrderServiceTest {
@Autowired
private OrderService orderService;
@MockBean
private PaymentService paymentService;
@MockBean
private EmailService emailService;
@Test
void shouldCreateOrder() {
when(paymentService.processPayment(any()))
.thenReturn(new PaymentResult(true, "txn-123"));
Order order = orderService.createOrder(new OrderRequest("item-1", 100));
assertNotNull(order);
verify(paymentService).processPayment(any());
verify(emailService).sendConfirmation(any());
}
}
SpyBean
@SpyBean оборачивает реальный бин из контекста шпионом Mockito. Реальные методы продолжают работать, но их можно перехватить и переопределить:
Пример кода
@SpringBootTest
class NotificationServiceTest {
@Autowired
private NotificationService notificationService;
@SpyBean
private AuditService auditService;
@Test
void shouldLogAuditEvent() {
notificationService.notifyUser(1L, "Сообщение");
verify(auditService).log(eq(1L), contains("Сообщение"));
}
@Test
void shouldHandleAuditFailure() {
doThrow(new RuntimeException("Audit unavailable"))
.when(auditService).log(anyLong(), anyString());
assertDoesNotThrow(
() -> notificationService.notifyUser(1L, "Сообщение")
);
}
}
Важные нюансы
- Начиная со Spring Boot 3.4 аннотации
@MockBeanи@SpyBeanобъявлены устаревшими (deprecated) в пользу@MockitoBeanи@MockitoSpyBean, а также поддержки черезBeanOverride. Однако они по-прежнему широко используются. - Каждая уникальная комбинация
@MockBean/@SpyBeanсоздаёт отдельный кэш контекста. Чрезмерное использование разных мок-бинов в разных тестах приведёт к множественным пересозданиям контекста.
На собеседовании: интервьюер хочет услышать разницу между
@MockBean(полная подмена) и@SpyBean(обёртка над реальным бином). Частая ошибка — не знать про влияние@MockBeanна кэширование контекста.