В чем разница между назначением assert (утверждений) в тестах и использованием моков (@Mock)?

«В чем разница между назначением assert (утверждений) в тестах и использованием моков (@Mock)?» — вопрос из категории Тестирование, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Assert (утверждения) и Mock (заглушки) решают разные задачи в unit-тестировании и используются вместе, а не вместо друг друга.

Компонент Назначение Пример (JUnit + Mockito)
Assert Проверка результата или состояния системы после выполнения тестируемого метода. Это валидация того, что код работает корректно. assertEquals(5, result); assertTrue(list.isEmpty()); assertThrows(ValidationException.class, () -> service.validate(null));
@Mock Изоляция тестируемого класса (SUT - System Under Test) от его внешних зависимостей (БД, API, другие сервисы). Позволяет контролировать их поведение в тесте. @Mock UserRepository repositoryMock; when(repositoryMock.findById(1L)).thenReturn(Optional.of(testUser));

Типичный поток unit-теста:

  1. Подготовка (Arrange): Создаем моки зависимостей и настраиваем их поведение (when(...).thenReturn(...)).
  2. Действие (Act): Вызываем тестируемый метод, передавая ему эти моки (обычно через конструктор или DI).
  3. Проверка (Assert): Утверждениями проверяем, что метод вернул ожидаемый результат и/или что с моками были вызваны ожидаемые методы.
@Test
void transferMoney_ShouldSucceed_WhenFundsAreSufficient() {
    // Arrange: Создаем моки зависимостей
    @Mock AccountRepository accountRepoMock;
    @Mock AuditService auditServiceMock;

    Account from = new Account(1L, 100.0);
    Account to = new Account(2L, 50.0);
    when(accountRepoMock.findById(1L)).thenReturn(Optional.of(from));
    when(accountRepoMock.findById(2L)).thenReturn(Optional.of(to));

    TransferService service = new TransferService(accountRepoMock, auditServiceMock);

    // Act
    service.transfer(1L, 2L, 30.0);

    // Assert: Проверяем ИЗМЕНЕНИЕ СОСТОЯНИЯ объектов И ВЗАИМОДЕЙСТВИЕ с моками
    assertEquals(70.0, from.getBalance(), 0.001); // Assert 1
    assertEquals(80.0, to.getBalance(), 0.001);   // Assert 2
    verify(auditServiceMock).logTransaction(1L, 2L, 30.0); // Assert 3: проверка вызова мока
}