Verificare în mocking

Introducere în testarea în Java

Maria Milusheva

Senior Software Engineer

Motivație: Fără valori returnate

În lecția anterioară, am testat prin aserțiuni pe valorile returnate.

  • Dar ce se întâmplă dacă nu există valori returnate?

  • Ce se întâmplă dacă valorile returnate nu sunt relevante?

Exemplu: salvarea într-o bază de date.

Grafic al unei baze de date în care sunt salvate fișiere

Introducere în testarea în Java

Exemplu: Baze de date

Baza de date – un depozit digital pentru stocarea, gestionarea și securizarea colecțiilor organizate de date. Există mulți furnizori: Logourile unor baze de date populare

  • Serverele de baze de date sunt durabile, sigure, fiabile și au capacitate nelimitată

  • Bazele de date reale sunt prea mari și complexe pentru teste unitare (pot fi utilizate în teste de integrare)

Introducere în testarea în Java

Exemplu: Mesaje de jurnal

Să presupunem că procesăm jurnale de mesaje:

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

InfoStore și ErrorStore

Sunt necesare doar interfețe de bază pentru ca testul să funcționeze:

// 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);
}
Introducere în testarea în Java

Mockito verify

Cum testăm că un mesaj a fost salvat fără a crea baze de date?

Aserțiune că un mock a fost utilizat:

import static org.mockito.Mockito.verify;

Aserțiune că un mock nu a fost utilizat:

import static org.mockito.Mockito.verifyNoInteractions;
Introducere în testarea în Java

Configurarea testului

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

Mesaje de eșec al testelor

Ce se întâmplă dacă mesajul creat este:

String message = "[ERROR] Process failed!"

Vom vedea eșecuri de test precum:

Wanted but not invoked:
infoStore.save("[ERROR] Process failed!");
Actually, there were zero interactions with this mock.
Introducere în testarea în Java

Tehnici avansate de verificare

Putem verifica de câte ori a fost apelat 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...");
Introducere în testarea în Java

Să exersăm!

Introducere în testarea în Java

Preparing Video For Download...