Weryfikacja w mockowaniu

Wprowadzenie do testowania w Javie

Maria Milusheva

Senior Software Engineer

Motywacja: brak wartości zwracanych

W poprzedniej lekcji i ćwiczeniach testowaliśmy, sprawdzając wartości zwracane.

  • Co jednak, jeśli nie ma wartości zwracanych?

  • Co jeśli wartości zwracane nie są istotne ani informacyjne?

Przykład: zapis do bazy danych.

Grafika bazy danych z zapisywanymi do niej plikami

Wprowadzenie do testowania w Javie

Przykład: Bazy danych

Baza danych – cyfrowe repozytorium do przechowywania, zarządzania i zabezpieczania uporządkowanych zbiorów danych. Istnieje wiele dostawców baz danych: Logo popularnych baz danych

  • Serwery baz danych są trwałe, bezpieczne, niezawodne i mają nieograniczoną pojemność

  • Rzeczywiste bazy danych są zbyt duże i złożone do testów jednostkowych (mogą być używane w testach integracyjnych)

Wprowadzenie do testowania w Javie

Przykład: Komunikaty logu

Załóżmy, że przetwarzamy logi:

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);
        }
    }
}
Wprowadzenie do testowania w Javie

InfoStore i ErrorStore

Do działania testu wystarczą podstawowe interfejsy:

// 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);
}
Wprowadzenie do testowania w Javie

Mockito verify

Jak przetestować, czy komunikat został zapisany, bez tworzenia baz danych?

Sprawdzenie, że mock został użyty:

import static org.mockito.Mockito.verify;

Sprawdzenie, że mock nie został użyty:

import static org.mockito.Mockito.verifyNoInteractions;
Wprowadzenie do testowania w Javie

Konfiguracja testu

@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); }
Wprowadzenie do testowania w Javie

Komunikaty o błędach testu

Co jeśli zamiast tego utworzymy komunikat:

String message = "[ERROR] Process failed!"

Wówczas zobaczymy błędy testu, takie jak ten:

Wanted but not invoked:
infoStore.save("[ERROR] Process failed!");
Actually, there were zero interactions with this mock.
Wprowadzenie do testowania w Javie

Dodatkowe techniki weryfikacji

Można zweryfikować dokładnie, ile razy wywołano 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...");
Wprowadzenie do testowania w Javie

Czas na ćwiczenia!

Wprowadzenie do testowania w Javie

Preparing Video For Download...