Verifiering vid mockning

Introduktion till testning i Java

Maria Milusheva

Senior Software Engineer

Motivation: Inga returvärden

I föregående lektion testade vi genom att kontrollera returvärden.

  • Men vad händer om det saknas returvärden?

  • Vad om returvärdena inte är viktiga eller informativa?

Exempel: spara till en databas.

Grafik av en databas där filer sparas in i den

Introduktion till testning i Java

Exempel: Databaser

Databas – ett digitalt arkiv för att lagra, hantera och skydda organiserade samlingar av data. Det finns många databasleverantörer: Logotyper för några populära databaser

  • Databasservrar är beständiga, säkra, tillförlitliga och har obegränsad kapacitet

  • Riktiga databaser är för stora och komplexa för enhetstester (men kan användas i integrationstester)

Introduktion till testning i Java

Exempel: Loggmeddelanden

Anta att vi bearbetar loggar:

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);
        }
    }
}
Introduktion till testning i Java

InfoStore och ErrorStore

Enbart grundläggande gränssnitt behövs för att testet ska fungera:

// 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);
}
Introduktion till testning i Java

Mockito verify

Hur kan vi testa att ett meddelande sparades utan att skapa några databaser?

Kontrollera att en mock användes:

import static org.mockito.Mockito.verify;

Kontrollera att en mock inte användes:

import static org.mockito.Mockito.verifyNoInteractions;
Introduktion till testning i Java

Testuppsättning

@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); }
Introduktion till testning i Java

Testfelmeddelanden

Vad händer om meddelandet vi skapar är:

String message = "[ERROR] Process failed!"

Då ser vi testfel som dessa:

Wanted but not invoked:
infoStore.save("[ERROR] Process failed!");
Actually, there were zero interactions with this mock.
Introduktion till testning i Java

Fler verifieringsknep

Vi kan verifiera exakt hur många gånger en logg anropades:

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...");
Introduktion till testning i Java

Nu kör vi en övning!

Introduktion till testning i Java

Preparing Video For Download...