Gymterview
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 на кэширование контекста.