Мокінг і стабінг в модульних тестах

Вступ до тестування в Java

Maria Milusheva

Senior Software Engineer

Мотивація: залежності

Пригадайте залежності з попереднього уроку: застосунок обміну валют залежить від банківського сервера: Схема Mermaid потоку залежностей у банківському демо

Неможливо перевірити обчислення, бо курси валют за своєю природою непередбачувані.

Вступ до тестування в Java

Керування залежностями в тестуванні

Mocking — створення симульованих об'єктів або поведінки для реальних об'єктів, які складно використовувати в тестах. Це дозволяє тестувати без зовнішніх залежностей.


import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

Приклад мокінгу

Вступ до тестування в Java

Мокінг

  • Mock = як дублер актора в виставі: удає реальний об'єкт настільки, наскільки потрібно тесту

Згадайте попередній урок:

public double convertEuroTo(String currency, double amount) {
    double rate = this.bank.getRateEuroTo(currency);
    return amount * rate;
}

➡ Створіть передбачуваний об'єкт EuropeanCentralBankServer для тестування

Вступ до тестування в Java

Мокінг: обмін валют

Ось як ми тестуємо з моками:

@Test
void convert_returnsExpectedValue() {
    EuropeanCentralBankServer bank = mock(EuropeanCentralBankServer.class);
    ExchangeApp exchangeApp = new ExchangeApp(bank);

// Потрібно запрограмувати мок, щоб він працював when(bank.getRateEuroTo("USD")).thenReturn(1.1);
// Викликає getRateEuroTo у мок-об'єкта, отримуючи заздалегідь задані значення double result = exchangeApp.convertEuroTo("USD", 1000); assertEquals(1100, result); // Тепер можна перевіряти точні значення }
Вступ до тестування в Java

Типова помилка

Ніколи не забувайте програмувати свої моки:

@Test
void convert_returnsExpectedValue() {
    EuropeanCentralBankServer bank = mock(EuropeanCentralBankServer.class);
    ExchangeApp exchangeApp = new ExchangeApp(bank);

    // Без програмування мока — мок-банк не знає, як відповідати на getRateEuroTo
    double result = exchangeApp.convertEuroTo("USD", 1000);

    assertEquals(1100, result); // Тест впаде через відсутність налаштування мока
}
Вступ до тестування в Java

Стабінг

Тест завершується помилкою:

org.opentest4j.AssertionFailedError: 
Expected :1100.0
Actual   :0.0

Програмування мока називають стабінгом.

Stubbing — надання мінімальних, наперед визначених відповідей на виклики під час тесту, зазвичай без реакції на все, що не запрограмовано для цього тесту.

Вступ до тестування в Java

Винятки з Mockito

Mockito також може імітувати помилки:

EuropeanCentralBankServer bank = mock(EuropeanCentralBankServer.class);
ExchangeApp exchangeApp = new ExchangeApp(bank);
// Замість thenReturn() використовуйте thenThrow()
when(bank.getRateEuroTo("USD"))
        .thenThrow(new RuntimeException("Bank server unavailable."));

exchangeApp.convertEuroTo("USD", 1000); // getRateEuroTo кине виняток
Вступ до тестування в Java

Давайте потренуємось!

Вступ до тестування в Java

Preparing Video For Download...