Vai al contenuto
SDETRole
SDETRole

Glossario · Fondamenti del testing

Test double

Detto anche: controfigura di test, oggetto mock, mock object, test stub

Definizione

Qualsiasi oggetto che sostituisce una dipendenza reale in un test, come dummy, stub, fake, spy o mock, così il codice sotto test gira in modo veloce e prevedibile.

Un test double sostituisce una dipendenza reale, come un gateway di pagamento, un database, un orologio o un servizio email, con qualcosa che il test controlla. Il nome, reso popolare da Gerard Meszaros, viene dalla controfigura (stunt double) del cinema. I double rendono i test veloci e deterministici e ti permettono di simulare situazioni difficili da riprodurre nella realtà, come un timeout o una carta rifiutata.

I cinque tipi

Tipo Cosa fa Esempio
Dummy Passato solo per riempire un parametro, mai usato Un logger null o vuoto che il metodo richiede ma che questo test non tocca mai
Stub Restituisce risposte predefinite alle chiamate rates.getRate("EUR") restituisce sempre 0.92
Spy Uno stub che registra anche come è stato chiamato Registra che send() è stato chiamato una volta con un certo indirizzo
Mock Preprogrammato con aspettative; il test verifica le interazioni Verifica che gateway.charge(4999) sia stato chiamato esattamente una volta
Fake Un’implementazione funzionante ma semplificata Un repository in memoria basato su una HashMap

Nel linguaggio comune si dice “mock” per tutti questi, e librerie come Mockito creano oggetti che possono fare da stub, spy o mock. Conoscere la distinzione aiuta comunque, soprattutto stub contro mock: uno stub fornisce input al codice sotto test (verifica dello stato), mentre un mock controlla gli output che il codice invia alle sue dipendenze (verifica del comportamento).

Esempio (JUnit 5 con Mockito)

@Test
void declinedCardDoesNotSendConfirmation() {
    PaymentGateway gateway = mock(PaymentGateway.class);
    EmailService email = mock(EmailService.class);
    when(gateway.charge(4999)).thenReturn(PaymentResult.DECLINED); // stub

    var checkout = new Checkout(gateway, email);
    var result = checkout.placeOrder(4999);

    assertEquals(OrderStatus.PAYMENT_FAILED, result.status());
    verify(email, never()).sendConfirmation(any()); // mock-style verification
}

(Gli import statici da org.mockito.Mockito, org.mockito.ArgumentMatchers e org.junit.jupiter.api.Assertions sono omessi.)

Errori comuni

  • Mockare tutto. I test che verificano ogni chiamata interna si rompono a ogni refactoring e possono passare mentre l’integrazione reale è rotta. Usa i mock ai confini architetturali; al loro interno preferisci oggetti reali o fake.
  • Double che si allontanano dalla realtà. Un’API stubbata che restituisce un campo che il servizio reale ha rinominato mesi fa dà una falsa sicurezza. I contract test e qualche test di integrazione reale mantengono onesti i double.
  • Mockare tipi che non ti appartengono. Incapsula i client di terze parti in una tua interfaccia e crea il double di quella.

Scrivi per cercare in tutto SDETRole.

Ricerca full-text con Pagefind · funziona nel tuo browser Apri la pagina di ricerca →