JavaRush /Курси /Модуль 5. Spring /Лекція 132: Unit-тести з використанням JUnit 5

Лекція 132: Unit-тести з використанням JUnit 5

Модуль 5. Spring
Рівень 9 , Лекція 1
Відкрита

Сьогодні ми вивчимо основи Unit-тестування з використанням JUnit 5.

Давай розберемося, як використати цю силу для створення якісного й безпечного коду.

Що таке JUnit 5 і навіщо він потрібен?

JUnit 5 — це сучасна версія популярного фреймворка для тестування на Java. Його мета — допомогти розробникам писати якісні Unit-тести. Перевага JUnit 5 полягає в його модульності та гнучкості. Ось основні компоненти JUnit 5:

  • JUnit Platform: відповідає за запуск тестів.
  • JUnit Jupiter: надає нові функції та анотації для тестування.
  • JUnit Vintage: дозволяє запускати старі тести, написані на JUnit 3 і 4 (археологи, це для вас).

Чому JUnit 5? Бо:

  • Підтримує Java 8 і вище, включно з лямбдами та методами за замовчуванням.
  • Більше можливостей для налаштування життєвого циклу тестів.
  • Зручніша анотація @DisplayName, щоб твої тести виглядали красиво і зрозуміло.

Основні анотації JUnit 5

Анотації — це як вказівки для JUnit, які повідомляють йому, що і як тестувати.

@Test

Найголовніша анотація. Якщо ти хочеш, щоб код виконався як тест, просто познач метод цією анотацією.


import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

class MathTest {

    @Test
    void additionTest() {
        int result = 2 + 3;
        assertEquals(5, result, "2 + 3 має дорівнювати 5");
    }
}

@BeforeEach и @AfterEach

Використовуються для виконання дій до і після кожного тесту. Наприклад, налаштування тестового середовища або очищення ресурсів.


import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.AfterEach;

class LifecycleTest {

    @BeforeEach
    void setUp() {
        System.out.println("Підготовка перед тестом");
    }

    @AfterEach
    void tearDown() {
        System.out.println("Очищення після тесту");
    }

    @Test
    void simpleTest() {
        System.out.println("Виконання тесту");
    }
}

Виводи будуть такі:


Підготовка перед тестом
Виконання тесту
Очищення після тесту

@BeforeAll и @AfterAll

Використовуються для виконання дій до або після всіх тестів у класі. Ці методи повинні бути static.


import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.AfterAll;

class GlobalSetupTest {

    @BeforeAll
    static void init() {
        System.out.println("Підготовка перед ВСІМИ тестами");
    }

    @AfterAll
    static void cleanup() {
        System.out.println("Очищення після ВСІХ тестів");
    }

    @Test
    void testOne() {
        System.out.println("Перший тест");
    }

    @Test
    void testTwo() {
        System.out.println("Другий тест");
    }
}

Вивід:


Підготовка перед ВСІМИ тестами
Перший тест
Другий тест
Очищення після ВСІХ тестів

@DisplayName

Додай рослину в цифрову пустелю своїх тестів! Зроби їх гарнішими з @DisplayName.

@Test
@DisplayName("Перевірка додавання: 2 + 2 = 4")
void additionTest() {
    assertEquals(4, 2 + 2);
}

Основні Assertions

Assertions — це як контрольні точки. Вони перевіряють, чи правильно працює твій код.

Assertion Опис Приклад
assertEquals(expected, actual) Перевіряє, чи рівні очікуване і фактичне assertEquals(4, 2 + 2)
assertNotEquals(unexpected, actual) Перевіряє, що значення НЕ рівні assertNotEquals(5, 2 + 2)
assertTrue(condition) Підтверджує, що умова істинна assertTrue(2 + 2 == 4)
assertFalse(condition) Підтверджує, що умова хибна assertFalse(2 + 2 == 5)
assertNull(object) Перевіряє, що об'єкт дорівнює null assertNull(nullVariable)
assertNotNull(object) Перевіряє, що об'єкт НЕ дорівнює null assertNotNull(nonNullVariable)
assertThrows(exception, lambda) Перевіряє, що код викликає вказане виключення assertThrows(NumberFormatException.class, () -> Integer.parseInt("NaN"))

Приклад:

@Test
void testAssertions() {
    assertEquals(4, 2 + 2, "Додавання двох чисел повинно бути коректним");
    assertTrue(3 > 2, "3 більше за 2 - це правда");
    assertThrows(ArithmeticException.class, () -> {
        int result = 10 / 0;
    }, "Очікувалось ArithmeticException при діленні на 0");
}

Життєвий цикл тестів у JUnit 5

Тести в JUnit проходять через визначений життєвий цикл:

  1. Створюється об'єкт тестового класу.
  2. Викликається метод з анотацією @BeforeEach.
  3. Виконується тест.
  4. Викликається метод з анотацією @AfterEach.
  5. Повторюється для кожного тесту.

Методи з анотаціями @BeforeAll і @AfterAll виконуються один раз на весь клас.


Практика: Написання Unit-тестів для простих методів

Припустимо, у нас є клас Calculator:


class Calculator {

    int add(int a, int b) {
        return a + b;
    }

    int subtract(int a, int b) {
        return a - b;
    }

    int multiply(int a, int b) {
        return a * b;
    }

    int divide(int a, int b) {
        if (b == 0) {
            throw new IllegalArgumentException("Ділення на нуль не допускається");
        }
        return a / b;
    }
}

І тести до нього:


import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class CalculatorTest {

    Calculator calculator = new Calculator();

    @Test
    void testAddition() {
        assertEquals(5, calculator.add(2, 3), "2 + 3 має дорівнювати 5");
    }

    @Test
    void testSubtraction() {
        assertEquals(1, calculator.subtract(3, 2), "3 - 2 має дорівнювати 1");
    }

    @Test
    void testMultiplication() {
        assertEquals(6, calculator.multiply(2, 3), "2 * 3 має дорівнювати 6");
    }

    @Test
    void testDivision() {
        assertEquals(2, calculator.divide(6, 3), "6 / 3 має дорівнювати 2");
    }

    @Test
    void testDivisionByZero() {
        Exception exception = assertThrows(IllegalArgumentException.class, () -> calculator.divide(5, 0));
        assertEquals("Ділення на нуль не допускається", exception.getMessage());
    }
}

Ці тести перевіряють основні арифметичні операції і обробляють виключення при діленні на нуль.


Що найчастіше ставить людей у замішання?

  1. Чому тести не запускаються? Можливо, твій метод у тестовому класі не позначений @Test.
  2. Чому тест «падає»? Уважно прочитай повідомлення про помилку. Скоріше за все, очікування assertEquals не збігаються з фактичним результатом.
  3. Як писати тести до приватних методів? Часто приватні методи тестуються опосередковано через публічні.

JUnit 5 — потужний інструмент, і чим більше ти з ним практикуєшся, тим простіше писати якісні тести. Вперед — ламай свої баги в найкращих традиціях супергероїв!

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ