1. Бібліотека Mockito

Сьогодні ми познайомимося із просунутим тестуванням. А точніше, з бібліотекою Mockito. Навіть і не думай уникнути цієї справи.

По-перше, ця бібліотека – стандарт у тестуванні Spring. А це фактично є стандартом у галузі Java backend-розробки.

По-друге, тобі доведеться писати тести для свого Spring-коду. Єдиний спосіб зрозуміти, що написаний тобою бекенд працює як треба – це викликати методи його API. І зробити це за допомогою тестів у 10 разів легше, ніж без них. Ти скоро в цьому переконаєшся.

Додати бібліотеку Mockito до твого pom.xml можна за допомогою коду:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>4.2.0</version>
    <scope>test</scope>
</dependency>

Весь вихідний код проєкту Mockito можна знайти на GitHub.

2. Mock-об'єкти

Що ж таке ця Mockito і чому вона така хороша?

У процесі розвитку та становлення тестування часто виникала необхідність замість реального об'єкта підсунути коду якусь «заглушку».

Наприклад, тестується код, який працює з базою даних та щось там змінює. Бажано, щоб перед кожним тестом стан цієї бази був однаковим (інакше тести будуть різні). І базу хотілося б простішу, щоб швидко ці стани відкочувати.

Або, наприклад, ти тестуєш код, який надсилає корисні SMS. А безпосередньо для розсилок він використовує якийсь платний SMS Gateway. Було б добре тестування коду підсунути йому якийсь віртуальний Gateway, щоб не розсилати сотні SMS незрозуміло кому.

Або твій код запитує дані від інших вебсерверів, які банально недоступні на тестовому сервері. Або ти пишеш код для інтернет-платежів, який потрібно 50 разів протестувати і лише потім допускати до реальних фінансових каналів.

Думаю, ти розумієш… Віртуальні об'єкти, або об'єкти-заглушки – дуже корисна штука.

І тут виникає складність – статична типізація Java. Отже, щоб замість об'єкта типу RealDatabase присвоїти змінній посилання на об'єкт VirtualDatabase, потрібно успадкувати клас VirtualDatabase від RealDatabase.

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

І тут нам на допомогу приходить DynamicProxy (докладніше можна почитати тут), який з'явився ще в Java 5. Він дозволяє створювати віртуальні об'єкти, до яких у компілятора немає претензій.

Такі віртуальні об'єкти називають mock'ами (від слова mock – макет). Бібліотеці Mockito вдалося піднести роботу з цими моками на небувалу висоту. Звідси, до речі, назва бібліотеки.

3. Анотація @ExtendWith

Бібліотека Mockito чудово працює разом із JUnit: її навіть можна розглядати як його розширення.

Є два способи активувати роботу бібліотеки Mockito у ваших unit-тестах. Перший спосіб – це додати спеціальну анотацію:


@ExtendWith(MockitoExtension.class)
public class MockitoAnnotationTest {
    ...
}

Другий спосіб – увімкнути її роботу за допомогою методу openMocks():


public class MockitoAnnotationTest {
    @BeforeEach
    public void init() {
        MockitoAnnotations.openMocks(this);
   }
}

Найчастіше ти зустрічатимеш перший варіант, але корисно знати, що є й другий.