Mocking și Stubbing în Teste Unitare

Introducere în testarea în Java

Maria Milusheva

Senior Software Engineer

Motivație: Dependențe

Fluxul de dependențe din lecția anterioară: aplicația de schimb valutar depinde de serverul bancar: Un grafic Mermaid al fluxului de dependențe în demo-ul bancar

Impossibil să verificăm calculele deoarece ratele de schimb valutar sunt imprevizibile.

Introducere în testarea în Java

Gestionarea dependențelor în testare

Mocking - crearea unor obiecte sau comportamente simulate pentru obiecte reale dificil de utilizat în teste, permițând testarea fără dependențe externe.


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

Exemplu de mocking

Introducere în testarea în Java

Mocking

  • Mock = ca un actor dublură într-o piesă, care imită obiectul real doar în scopul testului

Luați în considerare lecția anterioară:

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

➡ Creați un obiect predictibil pentru EuropeanCentralBankServer în scopul testării

Introducere în testarea în Java

Mocking: Schimb valutar

Astfel se testează cu mock-uri:

@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 }
Introducere în testarea în Java

Greșeală frecventă

Nu trebuie să uităm să programăm mock-urile:

@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
}
Introducere în testarea în Java

Stubbing

Testul eșuează cu:

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

Programarea unui mock se numește stubbing.

Stubbing - furnizarea unor răspunsuri predefinite minimale la apelurile din test, fără a răspunde la nimic în afara celor programate.

Introducere în testarea în Java

Excepții cu Mockito

Mockito poate simula și scenarii de eroare:

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
Introducere în testarea în Java

Să exersăm!

Introducere în testarea în Java

Preparing Video For Download...