Skip to main content

Як DI допомагає при unit-тестуванні?

Dependency Injection (DI) кардинально спрощує unit-тестування, тому що дозволяє ізолювати клас, що тестується, від його реальних залежностей.

Розберемо детально.


1. Без DI - тестувати майже неможливо

Якщо клас сам створює свої залежності, він "намертво" прив'язаний до конкретних реалізацій.

java
class UserService { private Database db = new MySQLDatabase(); // жорстка залежність public User getUser(int id) { return db.findUser(id); } }

Проблема: Щоб протестувати UserService, доведеться:

  • налаштовувати справжню базу даних,
  • очищати таблиці після кожного тесту,
  • чекати реальних запитів (повільно і нестабільно).

Такий тест уже не unit-тест, а інтеграційний.


2. З DI - можна підмінити залежність на "фейкову"

Коли залежність впроваджується ззовні, її легко замінити на mock чи stub.

java
class UserService { private final Database db; public UserService(Database db) { this.db = db; } public User getUser(int id) { return db.findUser(id); } }

Тепер у тесті можна підставити фіктивну реалізацію:

java
class MockDatabase implements Database { public User findUser(int id) { return new User("TestUser"); } } @Test void testGetUser() { Database mockDb = new MockDatabase(); UserService service = new UserService(mockDb); assertEquals("TestUser", service.getUser(1).getName()); }

Результат:

  • Жодних реальних підключень.
  • Тест миттєвий, стабільний, ізольований.
  • Перевіряється лише логіка самого класу, а не поведінка залежностей.

3. Контейнери DI прискорюють налаштування тестів

Якщо в проекті використовується IoC-контейнер (Spring, Guice і т. д.), він сам підставляє потрібні залежності, а для тестів можна налаштувати тестові конфігурації, наприклад підмінити реальні компоненти на mock-версії.

java
@SpringBootTest @MockBean(Database.class) class UserServiceTest { @Autowired private UserService userService; @Test void testGetUser() { when(database.findUser(1)).thenReturn(new User("Mocked")); assertEquals("Mocked", userService.getUser(1).getName()); } }

4. Чому це важливо

DI створює архітектуру, де:

  • Класи не залежать від конкретних реалізацій,
  • Всі залежності можна ізолювати, підміняти і контролювати,
  • Тести стають швидкими, детермінованими і відтворюваними.

Висновок:

DI робить можливим чисте unit-тестування: залежності більше не потрібно запускати - їх можна вколоти як підроблені реалізації. Це дозволяє тестувати лише логіку класу, а не всю систему.

Хочеш - покажу короткий приклад на Python чи Java, де видно, як DI скорочує код тесту в 3 рази?

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.