Test Doubles — vad är det, typer och tillämpning

Författare: IT Sectr Publicerad: 2026-04-10 Lästid: 9 min

Test Doubles — är ersättningsobjekt som används i enhetstester istället för riktiga beroenden. Termen introducerades av Gerard Meszaros i boken “xUnit Test Patterns” (2007) som ett samlingsbegrepp för Mock, Stub, Fake, Spy och Dummy. Enligt Martin Fowler (2024), gör Test Doubles det möjligt att isolera den testade komponenten från dess omgivning, vilket gör testerna deterministiska, snabba och oberoende av externa tjänster.

Huvudpunkter

  • Test Doubles — samlingsbegrepp för alla typer av ersättningsobjekt i testning
  • Mock kontrollerar interaktion: vilka metoder som anropats och med vilka argument
  • Stub returnerar förbestämda värden utan att kontrollera anrop
  • Fake — en förenklad fungerande implementering (t.ex. in-memory databas)
  • Spy registrerar anrop för senare verifiering, Dummy fyller parametrar

Vad är Test Doubles?

Test Doubles — är en term från bilindustrin (stuntman, “double” för skådespelare), överförd till mjukvaruutveckling. Precis som en stuntman ersätter en skådespelare i en farlig scen, ersätter Test Double en verklig komponent i ett testscenario. Detta är nödvändigt när det verkliga beroendet inte är tillgängligt, är långsamt, icke-deterministiskt eller har biverkningar.

Konceptet Test Double omfattar fem specifika typer, var och en med sin egen uppgift. Meszaros typologi är kanonisk och används i alla moderna testningsguider. Skillnaden mellan typerna ligger i graden av kontroll och verifiering: från enkel parameterifyllnad (Dummy) till fullständig kontroll av anropssekvensen (Mock).

Varför Test Doubles behövs

Huvudsyftet med Test Doubles är isolering av den testade modulen. I mobil utveckling är verkliga beroenden API-servrar, databaser, filsystem, enhetssensorer, systemtjänster (LocationManager, Camera, Bluetooth). Direkt användning av dessa komponenter gör testerna långsamma, bräckliga och beroende av omgivningen. Enligt Google Testing Blog (2023) körs välisolerade enhetstester på millisekunder, medan integrationstester tar sekunder och minuter.

Fem typer av Test Doubles

Klassificeringen av Gerard Meszaros omfattar fem typer av Test Doubles, som skiljer sig åt i beteende och användningssyfte. Att förstå skillnaderna mellan dem är grunden för korrekt enhetstestning.

Dummy

Dummy — är ett objekt som skickas till den testade metoden men aldrig används. Dummy behövs bara för att uppfylla metodens signatur. I Kotlin är detta ofta null, emptyList() eller ett objekt med ersättningar. Dummy bör inte innehålla någon logik — om det anropas bör testet misslyckas.

Fake

Fake — är en förenklad men fungerande implementering av ett gränssnitt. Till skillnad från Mock och Stub innehåller Fake verklig affärslogik, men i förenklad form. Det klassiska exemplet — InMemoryUserRepository, som lagrar data i HashMap istället för i en databas. Fake används när logik som beror på tillstånd behöver testas, men utan overhead av verklig infrastruktur.

TypSyfteExempel
DummyFylla parameternull, tomt objekt
FakeFungerande förenklad implementeringInMemoryRepository
StubReturnera fast värdewhen(api.getUser()).thenReturn(user)
SpyRegistrera anrop för kontrollverify(spy).save(user)
MockKontrollera interaktionverify(mock).sendEmail(email)

Stub

Stub returnerar förbestämda värden på specifika anrop. Stub kontrollerar inte om det anropats — det bara tillhandahåller data. I Mockito skapas Stub via when(method).thenReturn(value). Stub är idealisk för testning när beroendet måste returnera ett specifikt värde, men själva faktumet att det anropas är inte viktigt.

Spy

Spy — är ett omslag runt ett verkligt objekt som registrerar alla anrop för senare verifiering. Till skillnad från Mock, delegerar Spy anrop till det verkliga objektet, men gör det möjligt att kontrollera att de inträffade. I Mockito skapas Spy via spy(realObject). Spy är användbart för partiell mockning när du vill använda ett verkligt objekt men kontrollera vissa anrop.

Mock

Mock — är ett objekt med fördefinierade anropsförväntningar. Mock kontrollerar om specifika metoder anropats med specifika argument och i en specifik ordning. Till skillnad från Stub fokuserar Mock på beteendeverifiering, inte på att returnera data. Mock är den kraftfullaste och mest använda typen av Test Double i mobil utveckling.

Mock och Stub: viktiga skillnader

Skillnaden mellan Mock och Stub orsakar ofta förvirring även bland erfarna utvecklare. Huvudskillnaden ligger i syftet: Stub kontrollerar tillstånd (state verification), Mock kontrollerar beteende (behavior verification).

Stub svarar på frågan: “returnerade koden rätt resultat?”. Mock svarar på frågan: “anropade koden rätt metoder med rätt argument?”. I mobil utveckling används Stub när resultatet är viktigt (t.ex. data från ett repository), och Mock när biverkningar är viktiga (t.ex. skicka e-post, skriva till databas).

kotlin
// Stub: tillståndskontroll
every { repository.getUsers() } returns listOf(user)
val result = useCase.getUsers()
assertEquals(1, result.size)

// Mock: beteendekontroll
every { analytics.logEvent("purchase") } returns Unit
useCase.purchase(item)
verify { analytics.logEvent("purchase") }

Exempel på Test Doubles i Kotlin

Praktiska exempel på alla fem typer av Test Doubles i Kotlin med användning av MockK — det mest populära mocking-biblioteket för Android-projekt.

Fake: InMemoryUserRepository

kotlin
class InMemoryUserRepository : UserRepository {
    private val store = mutableMapOf<String, User>()

    override fun save(user: User) {
        store[user.email] = user
    }

    override fun findByEmail(email: String): User? {
        return store[email]
    }
}

Stub + Mock: UseCase-test

kotlin
class RegisterUseCaseTest {
    private val api = mockk<AuthApi>()
    private val repo = spyk(InMemoryUserRepository())
    private val useCase = RegisterUseCase(api, repo)

    fun `register user successfully`() = runTest {
        // Stub: returnera fast API-svar
        coEvery { api.register("test@test.com") } returns AuthResult.Success("token123")

        val result = useCase.execute("test@test.com")

        // Verify: kontrollera att användaren har sparats
        verify { repo.save(any()) }
        assertTrue(result.isSuccess())
    }
}

Dummy: test med oanvänd parameter

kotlin
data class Logger(val appContext: Context, val format: FormatType)

fun `test logger with dummy context`() {
    // Dummy: Context används inte inom Logger
    val dummyContext = mockk<Context>()
    val logger = Logger(dummyContext, FormatType.JSON)
    assertEquals(FormatType.JSON, logger.format)
}

När ska vilken typ användas i mobil utveckling

Valet av Test Double-typ beror på vad som exakt testas: tillstånd, beteende eller integration. I mobil utveckling på Android och iOS har följande rekommendationer bildats.

För ViewModel och UseCase

Vid testning av ViewModel, använd Mock för beroenden som orsakar biverkningar (repositoryn, analys, navigering) och Stub för beroenden som returnerar data (API-klienter, ContentProvider). Detta gör det möjligt att kontrollera att ViewModel korrekt hanterar både lyckade och felaktiga scenarier.

För Repository och Datalager

Repository-nivå föredras Fake (in-memory databasimplementeringar) och Stub (fasta API-svar). Fake möjliggör testning av cache-logik och offline-läge utan konfiguration av SQLite. Stub simulerar olika HTTP-statusar: 200, 404, 500, timeout.

  • Enhetstester av affärslogik — Mock för alla externa beroenden, Dummy för oanvända parametrar
  • Integrationstester — Fake istället för Mock (kontrollera att komponenter fungerar tillsammans)
  • UI-tester — Stub för API-svar (via MockWebServer eller WireMock)
  • Cache-tester — Fake för databas (in-memory istället för Room/SQLite)
  • Asynkrona tester — Mock med stöd för korutiner (MockK + Turbine för Flow)

Vanliga misstag vid användning av ersättningar

Felaktig användning av Test Doubles — en av de vanligaste orsakerna till bräckliga tester som går sönder vid varje omfaktorering.

Over-mocking: överdriven användning av Mock

Det vanligaste misstaget — att mocka allt. Om varje beroende i ett test är ersatt med Mock, slutar testet att kontrollera verkligt beteende. Mock bör endast vara för externa beroenden (nätverk, databas, filsystem, systemtjänster). Interna komponenter i applikationen (Value Object, data class, enkla verktyg) bör inte ersättas.

Under-specification: otillräcklig specifikation

Det andra misstaget — att skapa en Mock utan att definiera förväntningar. Om en metod anropas utan every / when, returnerar Mock ett standardvärde (null, 0, false). Detta kan leda till falskt positiva tester när Mock tyst returnerar null och testet tolkar detta som korrekt beteende.

Over-verification: överdriven verifiering

Det tredje misstaget — att kontrollera varje anrop av varje Mock. Verify bör endast användas för anrop som är kritiska ur affärslogikens synvinkel. Överdriven verifiering gör tester bräckliga: ändring av anropsordningen i produktionskod bryter tester utan att ändra beteendet.

Vanliga frågor

Vad är skillnaden mellan Mock och Stub?

Stub returnerar data och kontrollerar tillstånd (vad som returnerades), medan Mock kontrollerar beteende (vilka metoder som anropades). Stub = “returnera X”, Mock = “kontrollera att Y anropades med argument Z”. I verkliga tester fungerar ett objekt ofta både som Stub och Mock samtidigt.

När ska man använda Fake istället för Mock?

Fake föredras framför Mock när tillståndsberoende logik testas: cachning, offline-läge, transaktioner. Fake (in-memory implementering) möjliggör testning av dessa scenarier utan bräckliga verify-anrop. Mock är mer lämpligt för att kontrollera datasändning: analys, push-notiser, e-post.

Vilket Test Doubles-bibliotek är bäst för Android?

För Android-projekt i Kotlin rekommenderas MockK. Det stödjer korutiner, suspend-funktioner, sealed class och extension-funktioner utan extra konfiguration. För Java-projekt är standarden fortfarande Mockito — det mest populära biblioteket med omfattande dokumentation.

Hur testar man Kotlin Flow med Test Doubles?

För att testa Kotlin Flow, använd biblioteket Turbine tillsammans med MockK. Turbine förenklar kontrollen av Flow-emissioner: du kan kontrollera värdenas ordning, flödets slutförande och undantag. Stub för Flow returnerar flowOf(value), Mock kontrollerar om Flow har samlats in.

Är det tillåtet att använda Test Doubles i UI-tester?

Ja, men på nivån av API-svar, inte UI-komponenter. Biblioteken MockWebServer (OkHttp) och WireMock gör det möjligt att ersätta HTTP-svar i UI-tester. Själva UI-komponenterna (Compose, SwiftUI Views) bör inte ersättas — deras beteende testas genom screenshot-tester och Espresso.

Sammanfattning

  • Test Doubles — samlingsbegrepp för fem typer av ersättningsobjekt: Mock, Stub, Fake, Spy, Dummy
  • Mock kontrollerar beteende (verify), Stub returnerar data (thenReturn), Fake — fungerar som en förenklad verklig implementering
  • Spy omsluter det verkliga objektet och registrerar anrop, Dummy fyller oanvända parametrar
  • Typologin av Gerard Meszaros — kanonisk klassificering som används i alla moderna mocking-ramverk
  • För Kotlin-projekt rekommenderas MockK, för Java — Mockito, för iOS — Cuckoo eller OHHTTPStubs
  • Vanliga misstag: over-mocking (ersätta allt), under-specification (odefinierade förväntningar), over-verification (överdriven verifiering)
  • Fake föredras framför Mock vid testning av logik med tillstånd — cachning, offline-läge och transaktioner

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å