Mockito — vad är det, nyckelbegrepp och funktionsprincip

Författare: IT Sectr Publicerad: 2026-04-08 Lästid: 8 min

Mockito är ett ramverk med öppen källkod för att skapa mock-objekt i enhetstester i Java och Kotlin, som gör det möjligt att isolera den testade koden från externa beroenden. Med dess hjälp ersätter utvecklaren riktiga repositories, API-klienter och databaser med kontrollerade substitut med specificerat beteende. Enligt data från Mockito.org används biblioteket i mer än 60% av Java-projekt som tillämpar enhetstestning.

Huvudpunkter

  • Mockito — bibliotek för att skapa mock-objekt som ersätter verkliga beroenden i tester.
  • Mock — ett substitutobjekt som imiterar beteendet hos en verklig komponent.
  • Stubbing — konfiguration av returvärdet vid anrop av mock-metoden.
  • Verify — kontroll av att metoden anropades med specifika argument.
  • @InjectMocks — automatisk injicering av mock-beroenden i det testade objektet.

Vad är Mockito?

Mockito är ett bibliotek med öppen källkod för att skapa mock-objekt (substitut) i enhetstester i Java, Kotlin och andra JVM-språk. Till skillnad från JUnit, som ansvarar för att köra tester, löser Mockito problemet med isolering — det ersätter de verkliga beroendena för den testade klassen med förutsägbara objekt.

Utan mockar kräver testning av en metod som använder en databas eller ett externt API att man sätter upp en verklig miljö — driftsätta databasen, starta en server. Mockito ersätter dessa beroenden med objekt med fast beteende: metoden repository.findById(1) returnerar alltid ett specifikt User-objekt utan att gå till databasen.

Arkitekturen för Mockito bygger på mönstret Proxy (för gränssnitt och klasser). Biblioteket genererar en underklass eller proxy för den angivna typen och fångar upp alla metodanrop, och returnerar standardvärden eller värden som ställts in via when().thenReturn().

Hur Mockito fungerar

Funktionsprincipen för Mockito bygger på tre grundläggande operationer: skapa mock, konfigurera beteende (stubbing) och verifiera anrop (verification). Varje operation använder statiska metoder från klassen org.mockito.Mockito — den mest laddade klassen i Java-ekosystemet enligt Maven Central-statistik. Alla anrop av mock-metoder registreras i minnet, vilket gör att de senare kan kontrolleras via verify.

Tre steg i ett test med Mockito

Ett typiskt test med Mockito består av tre faser: Arrange — skapa mockar och konfigurera stubs via when().thenReturn(), Act — anropa den testade metoden, Assert — kontrollera resultatet via assertEquals och verify(mock). Detta tillvägagångssätt kallas AAA (Arrange-Act-Assert).

Grundläggande exempel med en repository-mock

Låt oss titta på ett enkelt test där Mockito ersätter användararkivet. Metoden when().thenReturn() konfigurerar mocken så att anropet findById returnerar ett förberett User-objekt.

java
// Vi skapar en mock av arkivet
UserRepository mockRepo = mock(UserRepository.class);

// Konfigurerar beteende: vid findById(1) returnera användaren
when(mockRepo.findById(1)).thenReturn(new User("Alice"));

// Kontrollerar att metoden verkligen anropades
User result = mockRepo.findById(1);
assertEquals("Alice", result.getName());
verify(mockRepo).findById(1);

Skapa mock-objekt

Mockito erbjuder två sätt att skapa mockar: den statiska metoden mock(Class) och annoteringen @Mock med initiering via MockitoAnnotations.openMocks(). Det första sättet är kompakt för en-två mockar, det andra är bekvämt när det finns många beroenden — annoteringar minskar boilerplate-kod.

Via den statiska metoden mock()

Metoden mock() tar emot en klass och returnerar ett substitutobjekt som kan konfigureras via when().thenReturn(). Alla okonfigurerade metoder returnerar standardvärden: 0 för siffror, false för boolean, null för objekt.

java
ApiClient apiClient = mock(ApiClient.class);
Database database = mock(Database.class);

Via @Mock-annoteringen med JUnit 5

Annoteringen @Mock i kombination med @ExtendWith(MockitoExtension.class) skapar automatiskt mockar för alla fält i testklassen. Tillägget MockitoExtension ansvarar för initiering före varje test.

java
@ExtendWith(MockitoExtension.class)
class UserServiceTest {

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private UserService userService;

    @Test
    void getUserShouldReturnUserFromRepo() {
        when(userRepository.findById(1)).thenReturn(new User("Alice"));
        User result = userService.getUser(1);
        assertEquals("Alice", result.getName());
    }
}

Stubbing: konfigurera mock-beteende

Stubbing — processen att bestämma vad en mock-metod ska returnera när den anropas med specifika argument. Grundläggande syntax: when(mock.method(args)).thenReturn(value). För olika scenarier erbjuder Mockito flera varianter av then-metoder.

MetodSyfte
thenReturn(value)Returnerar alltid det angivna värdet
thenThrow(exception)Kastar ett undantag vid anrop
thenAnswer(answer)Beräknar returvärdet dynamiskt
thenCallRealMethod()Anropar den verkliga metoden (delvis mock)

Dynamiskt svar via thenAnswer

När returvärdet beror på anropsargumenten används thenAnswer med en lambda. Detta är användbart för att simulera arbete med verklig data — till exempel generering av ett ID baserat på det överförda objektet.

java
when(repository.save(any())).thenAnswer(invocation -> {
    User user = invocation.getArgument(0);
    user.setId(42);
    return user;
});

Verify: kontrollera interaktioner med mocken

Verify är en unik funktion i Mockito som äldre mock-objektbibliotek (EasyMock, jMock) inte erbjuder.

Verify gör tester mer tillförlitliga eftersom det inte bara kontrollerar returvärdet, utan även bieffekter — anrop av metoder som inte returnerar något resultat (void-metoder). Metoden verify(mock).methodName(args) kontrollerar om en specifik mock-metod anropades med de angivna argumenten. Detta gör det möjligt att testa inte bara resultatet, utan även processen — faktumet att beroendet användes.

Kontrollera antalet anrop

Som standard kontrollerar verify att metoden anropades exakt en gång. Om ett annat antal behövs — används times(n), atLeast(n), never() och andra modifierare från klassen Mockito.

java
// Kontrollera antalet anrop
verify(repository, times(3)).save(any());
verify(repository, never()).delete(any());
verify(repository, atLeastOnce()).findById(1);

// Kontrollera ordningen på anrop
InOrder inOrder = inOrder(repository);
inOrder.verify(repository).save(any());
inOrder.verify(repository).flush();

ArgumentCaptor för att fånga argument

När man behöver kontrollera med vilket exakt objekt metoden anropades, används ArgumentCaptor. Den fångar argumentets värde under anropet och gör det möjligt att kontrollera dess fält separat. ArgumentCaptor är särskilt användbar när den testade koden skapar ett objekt internt och skickar det till beroendet — du kan inte kontrollera detta objekt på annat sätt.

java
ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class);
verify(repository).save(captor.capture());
assertEquals("Alice", captor.getValue().getName());

Annotationerna @Mock och @InjectMocks

@Mock och @InjectMocks — två viktiga annoteringar i Mockito som avsevärt minskar boilerplate-kod. @Mock skapar en mock för ett fält, och @InjectMocks injicerar alla mockar från testklassen i det testade objektet via konstruktor, setter eller fält.

Mekanismen @InjectMocks försöker injicera beroenden i följande ordning: konstruktor med flest argument, setter efter typ, privat fält. Om ingen metod fungerar — förblir objektet med null-beroenden och testet misslyckas med NullPointerException.

Regler för användning av @InjectMocks

Det är viktigt att förstå: @InjectMocks analyserar inte fälttyper — den sätter in vilken mock som helst som är typkompatibel. Om en klass har två fält av samma typ — kan Mockito injicera fel mock. I sådana fall rekommenderas att använda en explicit konstruktor med överföring av mockar.

Mockito i Android-projekt

I Android-utveckling används Mockito tillsammans med JUnit för att testa ViewModel, Repository och UseCase. Eftersom dessa klasser körs på JVM utan Android-kontext, ersätter Mockito deras beroenden — Room DAO, Retrofit API, SharedPreferences — med stubs med förutsägbart beteende.

Gradle-konfiguration för Mockito

För att lägga till Mockito i ett Android-projekt räcker det att lägga till beroendet mockito-core eller mockito-inline (den senare stöder mockning av final-klasser och statiska metoder). Version 5.12.0 (2024) innehåller stöd för Java 21 och förbättrad integration med JUnit 5.

kotlin
// build.gradle.kts (modul)
dependencies {
    testImplementation("org.mockito:mockito-core:5.12.0")
    testImplementation("org.mockito:mockito-junit-jupiter:5.12.0")
}

Mockito och PowerMock: föråldrad praxis

Tidigare krävdes PowerMock för mockning av statiska metoder och konstruktorer — ett tillägg som fungerade via bytekod-instrumentering. Från och med Mockito 5.x med mockito-inline är denna funktionalitet inbyggd direkt: mockStatic(ClassName.class) gör det möjligt att mocka statiska metoder utan extra bibliotek.

Testa ViewModel med Mockito

Typiskt scenario: ViewModel anropar en metod i arkivet och omvandlar resultatet till UI-tillstånd. Mockito ersätter arkivet och testet kontrollerar att ViewModel korrekt hanterar ett lyckat svar och fel. Vid användning av Clean Architecture skapas mockar för varje lager: DataSource, Repository och UseCase — detta gör det möjligt att testa varje lager isolerat.

  • success case — when(repo.getData()).thenReturn(Result.success(data)) → vi kontrollerar state = Success(data).
  • error case — when(repo.getData()).thenReturn(Result.error(exception)) → vi kontrollerar state = Error(message).
  • loading state — verify att ViewModel satte isLoading = true före anropet till arkivet.

Vanliga frågor

Hur skiljer sig Mockito från MockK?

Mockito är ett bibliotek för Java och Kotlin som använder proxy och reflektion. MockK är ett Kotlin-first bibliotek med stöd för korutiner, tilläggsfunktioner och final-klasser utan extra konfiguration.

Hur skapar man en mock för en final-klass i Mockito?

Från och med Mockito 2.1 stöds mockning av final-klasser via opt-in. I version 5.x (mockito-inline) är detta aktiverat som standard. Lägg bara till beroendet mockito-inline och använd standardmetoden mock().

Vad är Spy i Mockito?

Spy är en delvis mock som som standard anropar verkliga metoder, men gör det möjligt att åsidosätta några av dem via when().thenReturn(). Spy är användbart för att testa äldre kod när hela klassen inte kan skrivas om.

Vad är skillnaden mellan thenReturn och thenAnswer?

thenReturn returnerar alltid samma värde, oavsett argumenten. thenAnswer beräknar returvärdet baserat på anropet — argument, själva mocken, tillstånd. För dynamiska svar, använd alltid thenAnswer.

Varför är verify viktigt i tester med mockar?

Verify kontrollerar inte bara resultatet, utan även processen — faktumet att beroendet användes. Detta är kritiskt för tjänster som måste spara data eller skicka meddelanden. Utan verify kommer testet inte att upptäcka att metoden inte anropade save() eller send().

Sammanfattning

  • Mockito — bibliotek för att skapa mock-objekt, de facto-standard för mockning i Java och Kotlin.
  • Mockar skapas via mock(Class) eller @Mock-annoteringen med MockitoExtension.
  • Stubbing via when().thenReturn() bestämmer beteendet för mock-metoder.
  • Verify kontrollerar faktumet och antalet anrop av mock-metoder med angivna argument.
  • @InjectMocks injicerar automatiskt mockar i det testade objektet.
  • Android-integration — Mockito används för att testa ViewModel, Repository och UseCase.
  • ArgumentCaptor fångar anropsargument för detaljerad kontroll av objektfält.

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också