Test Doubles — wat is het, soorten en toepassing

Auteur: IT Sectr Gepubliceerd: 2026-04-10 Leestijd: 9 min

Test Doubles — zijn vervangingsobjecten die in eenheidstests worden gebruikt in plaats van echte afhankelijkheden. De term is geïntroduceerd door Gerard Meszaros in het boek „xUnit Test Patterns“ (2007) als een overkoepelend begrip voor Mock, Stub, Fake, Spy en Dummy. Volgens Martin Fowler (2024), stellen Test Doubles in staat om het geteste component te isoleren van zijn omgeving, waardoor tests deterministisch, snel en onafhankelijk van externe services worden.

Belangrijkste

  • Test Doubles — overkoepelende term voor alle soorten vervangingsobjecten in testen
  • Mock controleert interactie: welke methoden zijn aangeroepen en met welke argumenten
  • Stub retourneert vooraf bepaalde waarden zonder aanroepen te controleren
  • Fake — een vereenvoudigde werkende implementatie (bijv. in-memory database)
  • Spy registreert aanroepen voor latere verificatie, Dummy vult parameters

Wat zijn Test Doubles?

Test Doubles — is een term uit de auto-industrie (stuntman, „double“ voor acteurs), overgebracht naar softwareontwikkeling. Zoals een stuntman een acteur vervangt in een gevaarlijke scène, vervangt Test Double een echt component in een testscenario. Dit is nodig wanneer de echte afhankelijkheid niet beschikbaar, traag, niet-deterministisch of met bijwerkingen is.

Het concept Test Double omvat vijf specifieke soorten, elk met een eigen taak. De typologie van Meszaros is canoniek en wordt gebruikt in alle moderne testhandleidingen. Het verschil tussen de typen zit in de mate van controle en verificatie: van eenvoudige parameterinvulling (Dummy) tot volledige controle van de aanroepvolgorde (Mock).

Waarom Test Doubles nodig zijn

Het hoofddoel van Test Doubles is isolatie van de geteste module. In mobiele ontwikkeling zijn echte afhankelijkheden API-servers, databases, bestandssysteem, apparaatsensoren, systeemdiensten (LocationManager, Camera, Bluetooth). Direct gebruik van deze componenten maakt tests traag, kwetsbaar en afhankelijk van de omgeving. Volgens Google Testing Blog (2023) worden goed geïsoleerde eenheidstests uitgevoerd in milliseconden, en integratietests in seconden en minuten.

Vijf soorten Test Doubles

De classificatie van Gerard Meszaros omvat vijf soorten Test Doubles, die verschillen in gedrag en gebruiksdoel. Het begrijpen van het verschil tussen hen is de basis van correct eenheidstesten.

Dummy

Dummy — is een object dat wordt doorgegeven aan de geteste methode, maar nooit wordt gebruikt. Dummy is alleen nodig om aan de methodehandtekening te voldoen. In Kotlin is dit vaak null, emptyList() of een object met vervangingen. Dummy mag geen logica bevatten — als het wordt aangeroepen, moet de test falen.

Fake

Fake — is een vereenvoudigde maar werkende implementatie van een interface. In tegenstelling tot Mock en Stub bevat Fake echte bedrijfslogica, maar in vereenvoudigde vorm. Het klassieke voorbeeld — InMemoryUserRepository, dat gegevens opslaat in HashMap in plaats van een database. Fake wordt gebruikt wanneer logica die afhankelijk is van toestand moet worden getest, maar zonder de overhead van echte infrastructuur.

TypeDoelVoorbeeld
DummyParameter invullennull, leeg object
FakeWerkende vereenvoudigde implementatieInMemoryRepository
StubVaste waarde retournerenwhen(api.getUser()).thenReturn(user)
SpyAanroepen registreren voor controleverify(spy).save(user)
MockInteractie controlerenverify(mock).sendEmail(email)

Stub

Stub retourneert vooraf bepaalde waarden op specifieke aanroepen. Stub controleert niet of het is aangeroepen — het levert gewoon gegevens. In Mockito wordt Stub gemaakt via when(method).thenReturn(value). Stub is ideaal voor testen wanneer de afhankelijkheid een specifieke waarde moet retourneren, maar het feit van de aanroep zelf niet belangrijk is.

Spy

Spy — is een wrapper rond een echt object dat alle aanroepen registreert voor latere verificatie. In tegenstelling tot Mock, delegeert Spy aanroepen naar het echte object, maar maakt het mogelijk te controleren dat ze hebben plaatsgevonden. In Mockito wordt Spy gemaakt via spy(realObject). Spy is nuttig voor gedeeltelijk mocking wanneer u een echt object wilt gebruiken maar sommige aanroepen wilt controleren.

Mock

Mock — is een object met vooraf gedefinieerde aanroepverwachtingen. Mock controleert of bepaalde methoden zijn aangeroepen met bepaalde argumenten en in een bepaalde volgorde. In tegenstelling tot Stub, richt Mock zich op gedragsverificatie, niet op het retourneren van gegevens. Mock is het krachtigste en meest gebruikte type Test Double in mobiele ontwikkeling.

Mock en Stub: belangrijkste verschillen

Het verschil tussen Mock en Stub veroorzaakt vaak verwarring, zelfs bij ervaren ontwikkelaars. Het belangrijkste verschil zit in het doel: Stub controleert toestand (state verification), Mock controleert gedrag (behavior verification).

Stub beantwoordt de vraag: „heeft de code het juiste resultaat geretourneerd?“. Mock beantwoordt de vraag: „heeft de code de juiste methoden met de juiste argumenten aangeroepen?“. In mobiele ontwikkeling wordt Stub gebruikt wanneer het resultaat belangrijk is (bijv. gegevens uit de repository), en Mock wanneer bijwerkingen belangrijk zijn (bijv. e-mail verzenden, schrijven naar database).

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

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

Voorbeelden van Test Doubles in Kotlin

Praktijkvoorbeelden van alle vijf soorten Test Doubles in Kotlin met behulp van MockK — de meest populaire mocking-bibliotheek voor Android-projecten.

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: vast API-antwoord retourneren
        coEvery { api.register("test@test.com") } returns AuthResult.Success("token123")

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

        // Verify: controleren dat gebruiker is opgeslagen
        verify { repo.save(any()) }
        assertTrue(result.isSuccess())
    }
}

Dummy: test met ongebruikte parameter

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

fun `test logger with dummy context`() {
    // Dummy: Context wordt niet gebruikt binnen Logger
    val dummyContext = mockk<Context>()
    val logger = Logger(dummyContext, FormatType.JSON)
    assertEquals(FormatType.JSON, logger.format)
}

Wanneer welk type te gebruiken in mobiele ontwikkeling

De keuze van het Test Double-type hangt af van wat precies wordt getest: toestand, gedrag of integratie. In mobiele ontwikkeling op Android en iOS zijn de volgende aanbevelingen ontstaan.

Voor ViewModel en UseCase

Bij het testen van ViewModel gebruikt u Mock voor afhankelijkheden die bijwerkingen veroorzaken (repositories, analytics, navigatie) en Stub voor afhankelijkheden die gegevens retourneren (API-cliënten, ContentProvider). Dit maakt het mogelijk te controleren of ViewModel zowel succesvolle als foutscenario's correct afhandelt.

Voor Repository en Gegevenslaag

Op Repository-niveau hebben Fake (in-memory database-implementaties) en Stub (vaste API-antwoorden) de voorkeur. Fake maakt het mogelijk cache-logica en offline modus te testen zonder SQLite-configuratie. Stub simuleert verschillende HTTP-statussen: 200, 404, 500, timeout.

  • Eenheidstests van bedrijfslogica — Mock voor alle externe afhankelijkheden, Dummy voor ongebruikte parameters
  • Integratietests — Fake in plaats van Mock (controleren of componenten samenwerken)
  • UI-tests — Stub voor API-antwoorden (via MockWebServer of WireMock)
  • Cache-tests — Fake voor database (in-memory in plaats van Room/SQLite)
  • Asynchrone tests — Mock met ondersteuning voor coroutines (MockK + Turbine voor Flow)

Veelvoorkomende fouten bij het gebruik van vervangingen

Onjuist gebruik van Test Doubles — een van de meest voorkomende oorzaken van kwetsbare tests die bij elke refactoring breken.

Over-mocking: overmatig gebruik van Mock

De meest voorkomende fout — alles mocken. Als elke afhankelijkheid in een test is vervangen door Mock, stopt de test met het controleren van echt gedrag. Mock zou alleen voor externe afhankelijkheden moeten zijn (netwerk, database, bestandssysteem, systeemdiensten). Interne componenten van de applicatie (Value Object, data class, eenvoudige hulpprogramma's) mogen niet worden vervangen.

Under-specification: onvoldoende specificatie

De tweede fout — het maken van een Mock zonder verwachtingen te definiëren. Als een methode wordt aangeroepen zonder every / when, retourneert Mock een standaardwaarde (null, 0, false). Dit kan leiden tot vals-positieve tests waarbij Mock stilzwijgend null retourneert en de test dit interpreteert als correct gedrag.

Over-verification: overmatige verificatie

De derde fout — elke aanroep van elke Mock controleren. Verify mag alleen worden gebruikt voor aanroepen die kritisch zijn vanuit het oogpunt van bedrijfslogica. Overmatige verificatie maakt tests kwetsbaar: verandering van de aanroepvolgorde in productiecode breekt tests zonder gedragsverandering.

Veelgestelde vragen

Wat is het verschil tussen Mock en Stub?

Stub retourneert gegevens en controleert de toestand (wat is geretourneerd), en Mock controleert het gedrag (welke methoden zijn aangeroepen). Stub = „geef X terug“, Mock = „controleer dat Y is aangeroepen met argument Z“. In echte tests fungeert een object vaak zowel als Stub als Mock tegelijkertijd.

Wanneer Fake gebruiken in plaats van Mock?

Fake heeft de voorkeur boven Mock wanneer toestandsafhankelijke logica wordt getest: caching, offline modus, transacties. Fake (in-memory implementatie) maakt het mogelijk deze scenario's te testen zonder kwetsbare verify-aanroepen. Mock is geschikter voor het controleren van gegevensverzending: analytics, pushmeldingen, e-mail.

Welke Test Doubles-bibliotheek is beter voor Android?

Voor Android-projecten in Kotlin wordt MockK aanbevolen. Het ondersteunt coroutines, suspend-functies, sealed classes en extension-functies zonder extra configuratie. Voor Java-projecten blijft Mockito de standaard — de populairste bibliotheek met uitgebreide documentatie.

Hoe test ik Kotlin Flow met Test Doubles?

Voor het testen van Kotlin Flow gebruikt u de bibliotheek Turbine in combinatie met MockK. Turbine vereenvoudigt het controleren van Flow-emissies: u kunt de volgorde van waarden, het beëindigen van de stroom en uitzonderingen controleren. Stub voor Flow retourneert flowOf(value), Mock controleert of Flow is verzameld.

Is het toegestaan Test Doubles te gebruiken in UI-tests?

Ja, maar op het niveau van API-antwoorden, niet UI-componenten. De bibliotheken MockWebServer (OkHttp) en WireMock maken het mogelijk HTTP-antwoorden in UI-tests te vervangen. UI-componenten zelf (Compose, SwiftUI Views) mogen niet worden vervangen — hun gedrag wordt getest via screenshot-tests en Espresso.

Samenvatting

  • Test Doubles — overkoepelende term voor vijf soorten vervangingsobjecten: Mock, Stub, Fake, Spy, Dummy
  • Mock controleert gedrag (verify), Stub retourneert gegevens (thenReturn), Fake — werkt als een vereenvoudigde echte implementatie
  • Spy omhult het echte object en registreert aanroepen, Dummy vult ongebruikte parameters
  • Typologie van Gerard Meszaros — canonieke classificatie gebruikt in alle moderne mocking-frameworks
  • Voor Kotlin-projecten wordt MockK aanbevolen, voor Java — Mockito, voor iOS — Cuckoo of OHHTTPStubs
  • Veelvoorkomende fouten: over-mocking (alles vervangen), under-specification (ongedefinieerde verwachtingen), over-verification (overmatige verificatie)
  • Fake heeft de voorkeur boven Mock bij het testen van toestandslogica — caching, offline modus en transacties

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook