Как менялась архитектура проекта при внедрении модульного тестирования?

«Как менялась архитектура проекта при внедрении модульного тестирования?» — вопрос из категории Тестирование, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Написание модульных тестов часто приводит к значительному рефакторингу и улучшению архитектуры. Вот основные изменения, которые я наблюдал:

  1. Повышение модульности: Код разбивается на мелкие, одноответственные классы и функции, которые легко тестировать изолированно.

    // Было: монолитный метод
    public class OrderService {
        public void processOrder(Order order) {
            // валидация, бизнес-логика, сохранение, отправка уведомлений
        }
    }
    
    // Стало: разделение ответственности
    public class OrderValidator { /* ... */ }
    public class OrderProcessor { /* ... */ }
    public class OrderRepository { /* ... */ }
    public class NotificationService { /* ... */ }
  2. Внедрение зависимостей (DI): Жёсткие зависимости заменяются на интерфейсы, что позволяет использовать моки в тестах.

    // Вместо прямого создания
    public class ReportGenerator {
        private DatabaseConnector connector = new DatabaseConnector();
    }
    
    // Используем внедрение через конструктор
    public class ReportGenerator {
        private final DataSource dataSource;
        public ReportGenerator(DataSource dataSource) {
            this.dataSource = dataSource; // Можем передать мок
        }
    }
  3. Упрощение логики: Сложные методы с множеством ветвлений (if/else, switch) рефакторятся в более простые и предсказуемые конструкции, что упрощает достижение полного покрытия тестами.

  4. Тесты как документация: Набор модульных тестов становится живой спецификацией, которая наглядно демонстрирует, как должны работать отдельные компоненты системы.