Verifica nel mocking

Introduzione al Testing in Java

Maria Milusheva

Senior Software Engineer

Motivazione: nessun valore di ritorno

Nella lezione precedente e negli esercizi abbiamo testato verificando i valori di ritorno.

  • Ma se non ci sono valori di ritorno?

  • E se i valori di ritorno non fossero utili o informativi?

Esempio: salvataggio su un database.

Grafica di un database con file salvati al suo interno

Introduzione al Testing in Java

Esempio: database

Database: archivio digitale per memorizzare, gestire e proteggere dati organizzati. Ci sono molti provider: I loghi di alcuni database popolari

  • I server di database sono durevoli, sicuri, affidabili e con capacità virtualmente illimitata

  • I database reali sono troppo grandi e complessi per i test unitari (ma si usano nei test di integrazione)

Introduzione al Testing in Java

Esempio: log

Supponiamo di processare log:

public class MessageProcessor {
    private InfoStore infoStore;  // Will store info log messages here
    private ErrorStore errorStore; // Will store error log messages here

    public void saveMessage(String message) {
        if (message.startsWith("[INFO]")) {
            infoStore.save(message);
        }
        if (message.startsWith("[ERROR]")) {
            errorStore.save(message);
        }
    }
}
Introduzione al Testing in Java

InfoStore ed ErrorStore

Per il test servono solo interfacce di base:

// Blueprints for InfoStore and ErrorStore
// Mocks don't need the mocked classes to be properly implemented
interface InfoStore {
    void save(String message);
}

interface ErrorStore {
    void save(String message);
}
Introduzione al Testing in Java

Mockito verify

Come testare che un messaggio sia stato salvato senza creare database?

Verifica che un mock sia stato usato:

import static org.mockito.Mockito.verify;

Verifica che un mock non sia stato usato:

import static org.mockito.Mockito.verifyNoInteractions;
Introduzione al Testing in Java

Setup del test

@Test
void process_savesToInfoStore_whenInfoMessage() {
  InfoStore infoStore = mock(InfoStore.class);
  ErrorStore errorStore = mock(ErrorStore.class);
  MessageProcessor messageProcessor = new MessageProcessor(infoStore, errorStore);

String message = "[INFO] Process started."; messageProcessor.saveMessage(message); // Will use either InfoStore or ErrorStore
// Verify which one of the two databases was used verify(infoStore).save(message); verifyNoInteractions(errorStore); }
Introduzione al Testing in Java

Messaggi di errore del test

E se invece il messaggio fosse:

String message = "[ERROR] Process failed!"

Vedremmo errori di test come:

Wanted but not invoked:
infoStore.save("[ERROR] Process failed!");
Actually, there were zero interactions with this mock.
Introduzione al Testing in Java

Altri trucchi di verifica

Possiamo verificare quante volte è stato invocato un log:

import static org.mockito.Mockito.times;
List<String> messages = new ArrayList<>(); // Create list and add elements
                messages.add("[INFO] Processing data...");
                messages.add("[INFO] Processing data...");
                messages.add("[INFO] Processing data...");

messageProcessor.saveMessageList(messages); // Save the three messages


verify(infoStore, times(3)).save("[INFO] Processing data...");
Introduzione al Testing in Java

Passiamo alla pratica !

Introduzione al Testing in Java

Preparing Video For Download...