Testning på avancerad nivå: JUnit, Mockito och integrationstester · Lektion

Spionera på riktiga objekt

Upptäck hur Mockito-spioner kan användas för att delvis mocka riktiga objekt, anropa riktiga metoder och samtidigt verifiera interaktioner.

Lektion 3 av 411 steg

Spionera på riktiga objekt är en gratis lektion i Testning på avancerad nivå: JUnit, Mockito och integrationstester på CoddyKit. Detta är lektion 3 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Testning på avancerad nivå: JUnit, Mockito och integrationstester, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Testning på avancerad nivå: JUnit, Mockito och integrationstester innehåller totalt 4 lektioner.

Vad är Mockito-spioner?

I Mockito har ni lärt er att skapa mocks för att styra objekts beteende helt och hållet. Men vad gör ni om ni bara vill ändra några metoder och behålla det ursprungliga beteendet för resten?

Då kommer spies till användning! En spy kapslar in ett verkligt objekt och låter er:

  • Anropa objektets riktiga metoder som standard.
  • Åsidosätta (stubba) specifika metoder så att de returnerar fördefinierade värden.
  • Verifiera interaktioner med det verkliga objektet.

Se det som ”partiell mocking” – ni använder det verkliga objektet, men med några justeringar.

Skapa er första spy

Det är enkelt att skapa en spy. I stället för Mockito.mock() använder ni Mockito.spy() och skickar in en instans av det verkliga objekt som ni vill spionera på.

Vi definierar en enkel klass, DataService, som vi använder i våra exempel. Den här tjänsten utför olika operationer.

import org.mockito.Mockito;

public class DataService {
    public String fetchData(String id) {
        return "Real data for " + id;
    }

    public int processData(String data) {
        return data.length();
    }
}

public class Main {
    public static void main(String[] args) {
        DataService realService = new DataService();
        DataService spyService = Mockito.spy(realService);

        System.out.println("Spy created successfully!");
    }
}

Spies anropar riktiga metoder

Det viktigaste kännetecknet för en spy är att den som standard anropar de riktiga metoderna i objektet som den kapslar in. Det skiljer sig från en mock, som saknar en riktig implementation och returnerar standardvärden.

Nu ska vi se hur vår spyService anropar en riktig metod:

import org.mockito.Mockito;

public class DataService {
    public String fetchData(String id) {
        System.out.println("--- Calling REAL fetchData for ID: " + id + " ---");
        return "Real data for " + id;
    }

    public int processData(String data) {
        return data.length();
    }
}

public class Main {
    public static void main(String[] args) {
        DataService realService = new DataService();
        DataService spyService = Mockito.spy(realService);

        String result = spyService.fetchData("123");
        System.out.println("Result from spy: " + result);

        int processed = spyService.processData("Hello");
        System.out.println("Processed data length: " + processed);
    }
}

Stubba en spy: åsidosätt beteendet

Även om spies som standard anropar riktiga metoder kan ni fortfarande stubba dem så att de returnerar specifika värden eller kastar undantag, precis som med mocks. På så sätt kan ni styra delar av objektets beteende.

När ni stubbar en spy är det dock ofta säkrare att använda syntaxen doReturn().when():

  • Mockito.when(spy.method()).thenReturn(value) kan först köra den riktiga metoden om den anropas under delen when().
  • Mockito.doReturn(value).when(spy).method() undviker att köra den riktiga metoden under stubbningen, vilket är viktigt om den riktiga metoden har sidoeffekter eller kastar undantag.

Stubbning av en spy i praktiken

Vi stubbar metoden fetchData i vår spyService så att den returnerar ett anpassat värde för ett specifikt ID, medan andra anrop fortfarande går till den riktiga metoden:

import org.mockito.Mockito;

public class DataService {
    public String fetchData(String id) {
        System.out.println("--- Calling REAL fetchData for ID: " + id + " ---");
        return "Real data for " + id;
    }

    public int processData(String data) {
        return data.length();
    }
}

public class Main {
    public static void main(String[] args) {
        DataService realService = new DataService();
        DataService spyService = Mockito.spy(realService);

        // Stubbing the spy for a specific input
        Mockito.doReturn("Mocked data for specific ID")
               .when(spyService)
               .fetchData("specialId");

        // This call will return the mocked data
        String result1 = spyService.fetchData("specialId");
        System.out.println("Result for specialId: " + result1);

        // This call will go to the real method
        String result2 = spyService.fetchData("regularId");
        System.out.println("Result for regularId: " + result2);
    }
}

Verifiera interaktioner med spies

Precis som med mocks kan ni använda Mockito.verify() för att säkerställa att vissa metoder anropades på er spy. Det är användbart för att bekräfta att koden interagerar med det verkliga objektet som förväntat.

verify() fungerar exakt likadant för spies som för mocks. Ni kan kontrollera:

  • Om en metod anropades.
  • Hur många gånger den anropades.
  • Vilka argument den anropades med.

Exempel på verifiering av spy-anrop

Vi verifierar att metoden fetchData anropades på spyn, även när den körde sin riktiga implementation:

import org.mockito.Mockito;

public class DataService {
    public String fetchData(String id) {
        System.out.println("--- Calling REAL fetchData for ID: " + id + " ---");
        return "Real data for " + id;
    }

    public int processData(String data) {
        return data.length();
    }
}

public class Main {
    public static void main(String[] args) {
        DataService realService = new DataService();
        DataService spyService = Mockito.spy(realService);

        // Call a method on the spy (it will execute the real method)
        spyService.fetchData("user1");
        spyService.processData("data1");
        spyService.fetchData("user2");

        // Verify interactions
        Mockito.verify(spyService).fetchData("user1");
        Mockito.verify(spyService, Mockito.times(2)).fetchData(Mockito.anyString());
        Mockito.verify(spyService).processData("data1");

        System.out.println("Verification successful!");
    }
}

Spies jämfört med mocks: den viktiga skillnaden

Det är viktigt att förstå när ni ska använda en spy i stället för en traditionell mock:

  • Mocks: Skapar ett helt simulerat objekt. Alla metoder är ”tomma” och returnerar standardvärden om ni inte uttryckligen stubbar dem. De passar bra när den enhet som testas ska isoleras.
  • Spies: Kapslar in ett verkligt objekt. Alla metoder kör sin riktiga implementation om ni inte uttryckligen stubbar dem. De är användbara när ni vill använda det mesta av objektets riktiga beteende men styra några specifika interaktioner.

Föredra mocks för verklig enhetsisolering. Använd spies när ni arbetar med komplexa objekt där bara några metoder behöver styras, eller med äldre kod.

När ska spies användas?

Spies är särskilt användbara i följande situationer:

  • Ni testar en klass som interagerar med ett komplext beroende och bara behöver åsidosätta en liten del av beroendets beteende.
  • Ni har en äldre klass med många metoder och det skulle vara omständligt att skapa en fullständig mock, men ni behöver säkerställa att vissa metoder anropas eller returnerar specifika värden.
  • Ni vill testa delar av ett verkligt objekts beteende utan att helt ersätta objektet.

Använd dem dock sparsamt. Ett överdrivet beroende av spies kan leda till mindre isolerade tester som blir svårare att underhålla.

Snabb kontroll: spy-beteende

Anta en klass Logger med metoden log(String message) som skriver ut till konsolen. Om ni skapar en spy av ett new Logger()-objekt, vad händer när ni anropar spyLogger.log("Test") utan någon stubbning?

Sammanfattning: spionera på verkliga objekt

Ni har nu lärt er om Mockito-spies!

  • Spies kapslar in verkliga objekt och låter er som standard använda deras riktiga metoder.
  • Ni skapar dem med Mockito.spy(realObject).
  • Ni kan stubba specifika metoder med doReturn().when(spy).method() för att åsidosätta deras beteende.
  • Ni kan verifiera interaktioner med spies genom att använda Mockito.verify(), precis som med mocks.
  • Använd spies försiktigt, främst när ni behöver delvis styra ett verkligt objekt i stället för att isolera det helt.

Denna flexibilitet hjälper er att skriva mer målinriktade tester för komplexa scenarier.

Gratis att börja

Lär dig Testning på avancerad nivå: JUnit, Mockito och integrationstester med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
12
Lektioner
48

Vanliga frågor

Är lektionen ”Spionera på riktiga objekt” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Testning på avancerad nivå: JUnit, Mockito och integrationstester, inklusive ”Spionera på riktiga objekt”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Testning på avancerad nivå: JUnit, Mockito och integrationstester innehåller totalt 4 lektioner.

Vad lär jag mig i ”Spionera på riktiga objekt”?

Upptäck hur Mockito-spioner kan användas för att delvis mocka riktiga objekt, anropa riktiga metoder och samtidigt verifiera interaktioner. Ni övar på Testning på avancerad nivå: JUnit, Mockito och integrationstester med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Testning på avancerad nivå: JUnit, Mockito och integrationstester?

Du behöver inga förkunskaper. Utbildningen i Testning på avancerad nivå: JUnit, Mockito och integrationstester på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”Spionera på riktiga objekt”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Testning på avancerad nivå: JUnit, Mockito och integrationstester-lektionen?

Ja. Varje Testning på avancerad nivå: JUnit, Mockito och integrationstester-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Stubbning av returvärden
  2. Argumentmatchare i Mockito
  3. Spionera på riktiga objekt
  4. Kasta exceptions och hantera konsekutiva anrop
← Tillbaka till Testning på avancerad nivå: JUnit, Mockito och integrationstester