Ответ
Зависимости класса должны быть изолированы с помощью тестовых двойников (Test Doubles), таких как моки (mocks) или стабы (stubs). Это позволяет тестировать логику класса в полной изоляции, делая тесты быстрыми, стабильными и не зависящими от внешних систем.
Основные подходы:
- Внедрение зависимостей (DI): Зависимости передаются через конструктор или сеттеры, что позволяет легко подменять их тестовыми двойниками.
- Использование библиотек мокирования: Например, Mockito, EasyMock.
Пример с Mockito и JUnit 5:
class OrderServiceTest {
@Mock
private PaymentGateway paymentGatewayMock; // Зависимость-мок
@Mock
private InventoryService inventoryServiceMock;
@InjectMocks
private OrderService orderService; // Зависимости внедряются сюда
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
void processOrder_ShouldChargePayment() {
// 1. Arrange (Подготовка): Настраиваем поведение мока.
when(inventoryServiceMock.isInStock("item123")).thenReturn(true);
when(paymentGatewayMock.charge(anyDouble())).thenReturn(true);
// 2. Act (Действие): Вызываем тестируемый метод.
boolean result = orderService.processOrder("item123", 100.0);
// 3. Assert (Проверка): Проверяем результат и взаимодействие.
assertTrue(result);
verify(paymentGatewayMock).charge(100.0); // Проверяем, что метод был вызван.
}
}
Ключевые принципы:
- Изоляция: Тест падает только при изменении логики тестируемого класса, а не его зависимостей.
- Предсказуемость: Поведение моков контролируется в тесте.
- Скорость: Моки работают в памяти, без сетевых вызовов или доступа к БД.