Mocking en stubbing in unit tests

Introductie tot testen in Java

Maria Milusheva

Senior Software Engineer

Motivatie: afhankelijkheden

Herinner de afhankelijkheidsstroom uit de vorige les: De valuta-app hangt af van de bankserver: Een Mermaid-grafiek van de afhankelijkheidsstroom in de bankdemo

Berekeningen zijn niet verifieerbaar omdat wisselkoersen per definitie onvoorspelbaar zijn.

Introductie tot testen in Java

Afhankelijkheden beheren in tests

Mocking: gesimuleerde objecten of gedrag maken voor echte objecten die lastig zijn in tests, zodat we kunnen testen zonder externe afhankelijkheden.


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

Mocking-voorbeeld

Introductie tot testen in Java

Mocking

  • Mock = als een stand-in acteur in een toneelstuk, speelt het echte object alleen voor de test na

Kijk naar de vorige les:

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

➡ Maak voor tests een voorspelbaar object voor EuropeanCentralBankServer

Introductie tot testen in Java

Mocking: valutaomzetting

Zo testen we met mocks:

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

// Need to program the mock so it works when(bank.getRateEuroTo("USD")).thenReturn(1.1);
// Roept getRateEuroTo aan op de mock en krijgt onze voorgeprogrammeerde waarde double result = exchangeApp.convertEuroTo("USD", 1000); assertEquals(1100, result); // We kunnen nu exact op retourwaarden asserten }
Introductie tot testen in Java

Veelgemaakte fout

Vergeet nooit je mocks te programmeren:

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

    // Geen mock-programmering - de mock weet niet hoe te reageren op getRateEuroTo
    double result = exchangeApp.convertEuroTo("USD", 1000);

    assertEquals(1100, result); // Faalt door ontbrekende mock-setup
}
Introductie tot testen in Java

Stubbing

De test faalt met:

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

Een mock programmeren heet stubbing.

Stubbing: minimale, vooraf gedefinieerde antwoorden geven op aanroepen tijdens de test, en verder niet reageren op iets buiten wat voor de test is ingesteld.

Introductie tot testen in Java

Exceptions met Mockito

Mockito kan ook foutscenario’s simuleren:

EuropeanCentralBankServer bank = mock(EuropeanCentralBankServer.class);
ExchangeApp exchangeApp = new ExchangeApp(bank);
// Instead of thenReturn() use thenThrow()
when(bank.getRateEuroTo("USD"))
        .thenThrow(new RuntimeException("Bank server unavailable."));

exchangeApp.convertEuroTo("USD", 1000); // getRateEuroTo will throw exception
Introductie tot testen in Java

Laten we oefenen!

Introductie tot testen in Java

Preparing Video For Download...