Spring Boot 4 – komplett guide · Lektion

Enhetstestning med JUnit och Mockito

Skriv effektiva enhetstester för komponenterna i ert tjänstelager med JUnit 5 och Mockito för att skapa mockar av beroenden.

Lektion 1 av 411 steg

Enhetstestning med JUnit och Mockito är en gratis lektion i Spring Boot 4 – komplett guide på CoddyKit. Detta är lektion 1 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 Spring Boot 4 – komplett guide, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Spring Boot 4 – komplett guide innehåller totalt 4 lektioner.

Välkommen till enhetstestning!

I den här lektionen lär du dig att skriva effektiva enhetstester för dina Spring Boot-applikationer, med särskilt fokus på servicelagret.

Enhetstester är avgörande för att säkerställa att koden fungerar som förväntat och för att upptäcka fel tidigt i utvecklingen. Vi använder JUnit 5 och Mockito.

Vad är enhetstestning?

Enhetstestning innebär att testa den minsta möjliga delen av kod, kallad en 'enhet', isolerat. I Java är en enhet vanligtvis en enskild metod eller klass.

  • Isolering: Tester körs oberoende av varandra och utan externa beroenden.
  • Snabbhet: De körs mycket snabbt, vilket gör det möjligt att köra dem ofta.
  • Tidig upptäckt: Upptäck fel innan de växer till större problem.

Introduktion till JUnit 5

JUnit 5 är det populäraste testningsramverket för Java. Det tillhandahåller annotationer och assertioner som hjälper dig att skriva strukturerade och lättlästa tester.

Nu ska vi titta på den grundläggande strukturen för en testklass. Lägg märke till att annotationen @Test markerar en metod som ett testfall.

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

class SimpleCalculator {
  int add(int a, int b) {
    return a + b;
  }
}

// This is a JUnit 5 test class
class SimpleCalculatorTest {

  @Test
  void testAddition() {
    SimpleCalculator calc = new SimpleCalculator();
    int result = calc.add(2, 3);
    // An 'assertion' checks if the result is correct
    assertEquals(5, result, "2 + 3 should be 5");
    System.out.println("Addition test passed!");
  }

  public static void main(String[] args) {
    // In a real project, JUnit runs tests automatically.
    // Here, we simulate a call for demonstration.
    System.out.println("--- Simulating JUnit Test ---");
    new SimpleCalculatorTest().testAddition();
    System.out.println("--- Simulation Complete ---");
  }
}

Fokus på servicelagret

I Spring Boot innehåller servicelagret vanligtvis programmets affärslogik. Det samordnar operationer och är ofta beroende av datarepositories.

Enhetstestning av tjänster är idealisk eftersom de:

  • Innehåller kärnlogiken.
  • Vanligtvis är vanliga Java-klasser.
  • Enkelt kan isoleras från externa system, till exempel databaser.

Utmaningen: Beroenden

Tjänster är ofta beroende av andra komponenter, till exempel ett UserRepository för att hämta användardata. När vi enhetstestar en tjänst vill vi inte ansluta till en riktig databas.

Det är här mockning kommer in i bilden! Vi behöver simulera dessa beroenden för att säkerställa att vårt test verkligen är ett ”enhetstest” (isolerat).

Introduktion till Mockito för mockning

Mockito är ett populärt mockningsramverk för Java. Det låter oss skapa ”mock”-objekt som simulerar riktiga objekts beteende.

I stället för att ett riktigt UserRepository kommunicerar med en databas anger vi för ett av Mockito skapat mockat repository exakt vad det ska returnera när vissa metoder anropas.

Konfigurera mockar med annoteringar

Mockito tillhandahåller praktiska annoteringar som förenklar skapandet och injiceringen av mockar:

  • @Mock: Skapar ett mock-objekt för den angivna typen.
  • @InjectMocks: Skapar en instans av klassen som testas och injicerar @Mock-objekten i den.
import org.mockito.Mock;
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;

// Simple dependent class (e.g., a repository)
class DataRepository {
  String findDataById(String id) {
    throw new UnsupportedOperationException("Not implemented for real use!");
  }
}

// Our service class under test
class MyService {
  private final DataRepository repository;

  MyService(DataRepository repository) {
    this.repository = repository;
  }

  String processData(String id) {
    return "Processed: " + repository.findDataById(id);
  }
}

class MyServiceTestSetup {

  @Mock
  DataRepository mockRepository; // Mock of DataRepository

  @InjectMocks
  MyService myService; // Service where mocks are injected

  MyServiceTestSetup() {
    // This initializes the mocks
    MockitoAnnotations.openMocks(this);
    System.out.println("Mocks initialized for MyServiceTest!");
    System.out.println("mockRepository is a Mockito mock: " + (mockRepository != null));
    System.out.println("myService has mock injected: " + (myService != null));
  }

  public static void main(String[] args) {
    System.out.println("--- Setting Up Mocks Demo ---");
    new MyServiceTestSetup();
    System.out.println("--- Demo Complete ---");
  }
}

Definiera mockbeteende: when().thenReturn()

När du har en mock måste du ange hur den ska bete sig. Använd Mockito.when().thenReturn() för att definiera vad en mockad metod ska returnera för specifika indata.

På så sätt kan tjänsten köra sin logik med testdata från mocken, utan att behöva en riktig databas eller extern tjänst.

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.mockito.Mock;
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;
import static org.mockito.Mockito.when;

// Re-using classes from previous example
class DataRepository {
  String findDataById(String id) {
    return "Real Data for " + id;
  }
}

class MyService {
  private final DataRepository repository;
  MyService(DataRepository repository) {
    this.repository = repository;
  }
  String processData(String id) {
    return "Processed: " + repository.findDataById(id);
  }
}

class MyServiceTestBehavior {

  @Mock
  DataRepository mockRepository;

  @InjectMocks
  MyService myService;

  MyServiceTestBehavior() {
    MockitoAnnotations.openMocks(this);
  }

  @Test
  void testProcessDataWithMock() {
    // 1. Define mock behavior: when findDataById("123") is called,
    //    return "Mocked Data".
    when(mockRepository.findDataById("123")).thenReturn("Mocked Data");

    // 2. Call the service method
    String result = myService.processData("123");

    // 3. Assert the result
    assertEquals("Processed: Mocked Data", result);
    System.out.println("Test passed! Result: " + result);
  }

  public static void main(String[] args) {
    System.out.println("--- Mock Behavior Demo ---");
    MyServiceTestBehavior test = new MyServiceTestBehavior();
    test.testProcessDataWithMock();
    System.out.println("--- Demo Complete ---");
  }
}

Verifiera interaktioner med verify()

Ibland är du inte bara intresserad av returvärdet, utan också av om en viss metod på en mock anropades och vilka argument som användes.

Mockitos metod verify() låter dig kontrollera att interaktionerna med dina mockar ägde rum som förväntat. Det är användbart för att kontrollera sidoeffekter.

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.mockito.Mock;
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.times;

// Re-using classes from previous example
class DataRepository {
  String findDataById(String id) {
    return "Real Data for " + id;
  }
}

class MyService {
  private final DataRepository repository;
  MyService(DataRepository repository) {
    this.repository = repository;
  }
  String processData(String id) {
    return "Processed: " + repository.findDataById(id);
  }
  void saveData(String id, String data) {
    // Imagine this saves to DB via repository
    repository.findDataById(id); // Example interaction
    System.out.println("Saving data via mock...");
  }
}

class MyServiceTestVerification {

  @Mock
  DataRepository mockRepository;

  @InjectMocks
  MyService myService;

  MyServiceTestVerification() {
    MockitoAnnotations.openMocks(this);
  }

  @Test
  void testProcessDataAndVerify() {
    // Define mock behavior
    when(mockRepository.findDataById("456")).thenReturn("Verify Data");

    // Call the service method
    String result = myService.processData("456");

    // Assert the result
    assertEquals("Processed: Verify Data", result);

    // Verify that findDataById was called exactly once with "456"
    verify(mockRepository, times(1)).findDataById("456");
    System.out.println("Test passed! Method interaction verified.");
  }

  public static void main(String[] args) {
    System.out.println("--- Mock Verification Demo ---");
    MyServiceTestVerification test = new MyServiceTestVerification();
    test.testProcessDataAndVerify();
    System.out.println("--- Demo Complete ---");
  }
}

Snabbkontroll: Mockitos roll

Vilken är Mockitos främsta roll när du enhetstestar en Spring-tjänst som är beroende av ett repository?

Sammanfattning: Bemästra enhetstestning

Grattis! Du har tagit dina första steg mot effektiv enhetstestning med Spring Boot.

  • Enhetstester verifierar små kodenheter isolerat.
  • JUnit 5 är vårt testningsramverk och använder @Test.
  • Vi fokuserar på servicelagret för affärslogik.
  • Mockito hjälper oss att skapa mock-objekt för beroenden.
  • Använd @Mock och @InjectMocks för att konfigurera tester.
  • Definiera mockbeteende med when().thenReturn().
  • Verifiera interaktioner med verify().

Fortsätt öva, så blir din kod mer robust än någonsin!

Gratis att börja

Lär dig Java 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
21
Lektioner
84

Vanliga frågor

Är lektionen ”Enhetstestning med JUnit och Mockito” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Spring Boot 4 – komplett guide, inklusive ”Enhetstestning med JUnit och Mockito”, 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 Spring Boot 4 – komplett guide innehåller totalt 4 lektioner.

Vad lär jag mig i ”Enhetstestning med JUnit och Mockito”?

Skriv effektiva enhetstester för komponenterna i ert tjänstelager med JUnit 5 och Mockito för att skapa mockar av beroenden. Ni övar på Spring Boot 4 – komplett guide 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 Spring Boot 4 – komplett guide?

Du behöver inga förkunskaper. Utbildningen i Spring Boot 4 – komplett guide 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 1 av 4.

Hur lång tid tar lektionen ”Enhetstestning med JUnit och Mockito”?

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 Spring Boot 4 – komplett guide-lektionen?

Ja. Varje Spring Boot 4 – komplett guide-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. Enhetstestning med JUnit och Mockito
  2. Integrationstestning med Spring Boot
  3. Slicetestning och Testcontainers
  4. Testa webbcontrollers med MockMvc
← Tillbaka till Spring Boot 4 – komplett guide