Ответ
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-теста:
- Подготовка (Arrange): Создаем моки зависимостей и настраиваем их поведение (
when(...).thenReturn(...)). - Действие (Act): Вызываем тестируемый метод, передавая ему эти моки (обычно через конструктор или DI).
- Проверка (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: проверка вызова мока
}