Ответ
Внедрение зависимостей (DI) — это архитектурный паттерн, при котором компонент получает свои зависимости (например, сервисы, репозитории, клиенты API) извне, а не создает их внутри себя. Для QA это критически важно, так как DI является основой для изоляции тестируемого модуля и подмены реальных зависимостей на заглушки (mocks/stubs).
Проблема без DI (сложное тестирование):
// Код тесно связан с конкретной реализацией. Невозможно протестировать EmailService отдельно от реального SMTP-сервера.
public class NotificationService {
private EmailSender emailSender = new RealEmailSender(); // Зависимость создается внутри
public void sendWelcome(User user) {
emailSender.send(user.getEmail(), "Welcome!");
}
}
Решение с DI (простое тестирование):
// Зависимость внедряется через конструктор.
public class NotificationService {
private final EmailSender emailSender;
public NotificationService(EmailSender emailSender) { // DI через конструктор
this.emailSender = emailSender;
}
public void sendWelcome(User user) {
emailSender.send(user.getEmail(), "Welcome!");
}
}
Как это используется в тестах (на примере Mockito для Java):
@Test
void sendWelcome_ShouldCallEmailSender() {
// 1. Создаем mock-зависимость
EmailSender mockEmailSender = Mockito.mock(EmailSender.class);
// 2. Внедряем mock в тестируемый сервис
NotificationService service = new NotificationService(mockEmailSender);
User testUser = new User("test@example.com");
// 3. Выполняем действие
service.sendWelcome(testUser);
// 4. Проверяем, что метод был вызван с правильными аргументами
Mockito.verify(mockEmailSender).send("test@example.com", "Welcome!");
}
Преимущества для тестирования:
- Изоляция: Можно тестировать бизнес-логику
NotificationService, не беспокоясь о работе реальногоEmailSender. - Контроль: Mock-объекты позволяют эмулировать любые сценарии (успех, ошибка, таймаут).
- Скорость: Тесты выполняются мгновенно, так как не требуют сетевых вызовов или доступа к БД.
Видео-ответы
▶
▶
▶
▶
▶
▶
▶
▶
▶