Mocking och stubbing i enhetstester

Introduktion till testning i Java

Maria Milusheva

Senior Software Engineer

Motivation: beroenden

Kom ihåg beroendeflödet från föregående lektion: valutaväxlingsappen är beroende av bankservern: Ett Mermaid-diagram över beroendeflödet i bankdemon

Omöjligt att verifiera beräkningar eftersom valutakurser är i grunden oförutsägbara.

Introduktion till testning i Java

Beroendehantering i testning

Mocking – att skapa simulerade objekt eller beteenden för riktiga objekt som är svåra att använda i tester, vilket gör att vi kan testa utan att förlita oss på externa beroenden.

Mockito – kraftfullt Java-bibliotek för att skapa mockar.

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

Exempel på mocking

Introduktion till testning i Java

Mocking

  • En mock är som en ersättande skådespelare i en pjäs – den låtsas vara det riktiga objektet, men bara i testets sammanhang

Betrakta föregående lektion:

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

➡ Skapa ett förutsägbart objekt för EuropeanCentralBankServer för testning

Introduktion till testning i Java

Mocking: valutaväxling

Så här testar vi med mockar:

@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);
// Calls getRateEuroTo from the mock object, obtaining our pre-programmed values double result = exchangeApp.convertEuroTo("USD", 1000); assertEquals(1100, result); // We can now assert on exact return values }
Introduktion till testning i Java

Vanligt misstag

Glöm aldrig att programmera dina mockar:

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

    // No mock programming - mock bank object doesn't know how to respond to getRateEuroTo
    double result = exchangeApp.convertEuroTo("USD", 1000);

    assertEquals(1100, result); // Will fail due to lack of mock setup
}
Introduktion till testning i Java

Stubbing

Testet misslyckas med:

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

Att programmera en mock kallas stubbing.

Stubbing – att ge minimala, fördefinierade svar på anrop som görs under testet, utan att svara på något utanför det som programmerats för testet.

Introduktion till testning i Java

Undantag med Mockito

Mockito kan också simulera felscenarier:

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
Introduktion till testning i Java

Nu kör vi en övning!

Introduktion till testning i Java

Preparing Video For Download...