Mock e stub nei test unitari

Introduzione al Testing in Java

Maria Milusheva

Senior Software Engineer

Motivazione: dipendenze

Ricorda il flusso di dipendenze della lezione precedente: l’app di cambio valuta dipende dal server bancario: Un grafico Mermaid del flusso di dipendenze nella demo bancaria

Impossibile verificare i calcoli perché i tassi di cambio sono intrinsecamente imprevedibili.

Introduzione al Testing in Java

Gestione delle dipendenze nei test

Mocking: creare oggetti o comportamenti simulati per oggetti reali difficili da usare nei test, così da testare senza dipendere da risorse esterne.

Mockito: potente libreria Java per creare mock.

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

Esempio di mocking

Introduzione al Testing in Java

Mocking

  • Mock = come una controfigura a teatro: finge l’oggetto reale solo per il test

Riprendiamo la lezione precedente:

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

➡ Crea un oggetto prevedibile di EuropeanCentralBankServer per i test

Introduzione al Testing in Java

Mocking: cambio valuta

Ecco come testare con i mock:

@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);
// Chiama getRateEuroTo dal mock, ottenendo il valore preimpostato double result = exchangeApp.convertEuroTo("USD", 1000); assertEquals(1100, result); // Ora possiamo verificare valori esatti }
Introduzione al Testing in Java

Errore comune

Non dimenticare mai di programmare i mock:

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

    // Nessuna programmazione del mock: l’oggetto bank non sa rispondere a getRateEuroTo
    double result = exchangeApp.convertEuroTo("USD", 1000);

    assertEquals(1100, result); // Fallirà per mancanza di setup del mock
}
Introduzione al Testing in Java

Stubbing

Il test fallisce con:

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

Programmare un mock si chiama stubbing.

Stubbing: fornire risposte minime e predefinite alle chiamate durante il test, di solito ignorando tutto ciò che non è previsto dal test.

Introduzione al Testing in Java

Eccezioni con Mockito

Mockito può simulare anche scenari di errore:

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
Introduzione al Testing in Java

Passiamo alla pratica !

Introduzione al Testing in Java

Preparing Video For Download...