Test Doubles — mi ez, típusok és alkalmazás

Szerző: IT Sectr Megjelenés: 2026-04-10 Olvasási idő: 9 perc

Test Doubles — olyan helyettesítő objektumok, amelyeket egységtesztekben használnak valós függőségek helyett. A kifejezést Gerard Meszaros vezette be „xUnit Test Patterns“ (2007) című könyvében a Mock, Stub, Fake, Spy és Dummy átfogó fogalmaként. Martin Fowler (2024) szerint a Test Doubles lehetővé teszi a tesztelt komponens elkülönítését a környezetétől, ami determinisztikussá, gyorssá és külső szolgáltatásoktól függetlenné teszi a teszteket.

FŐbb pontok

  • Test Doubles — átfogó kifejezés a helyettesítő objektumok összes típusára a tesztelésben
  • Mock ellenőrzi az interakciót: mely metódusok lettek meghívva és milyen argumentumokkal
  • Stub előre meghatározott értékeket ad vissza a hívások ellenőrzése nélkül
  • Fake — egy egyszerűsített, de működő implementáció (például in-memory adatbázis)
  • Spy rögzíti a hívásokat későbbi ellenőrzéshez, Dummy kitölti a paramétereket

Mik azok a Test Doubles?

Test Doubles — az autóiparból származó kifejezés (kaszkadőr, „dublőr“ a színészek számára), átültetve a szoftverfejlesztésbe. Ahogy a kaszkadőr helyettesíti a színészt egy veszélyes jelenetben, a Test Double helyettesíti a valós komponenst egy tesztforgatókönyvben. Ez akkor szükséges, amikor a valós függőség nem érhető el, lassú, nem determinisztikus, vagy mellékhatásai vannak.

A Test Double fogalma öt konkrét típust foglal magában, amelyek mindegyike saját feladatát oldja meg. Meszaros tipológiája kanonikus, és minden modern tesztelési útmutatóban használatos. A típusok közötti különbség az ellenőrzés és verifikáció mértékében rejlik: az egyszerű paraméterkitöltéstől (Dummy) a hívási sorrend teljes ellenőrzéséig (Mock).

Miért van szükség Test Doubles-re

A Test Doubles fő célja a tesztelt modul elkülönítése. A mobil fejlesztésben a valós függőségek API szerverek, adatbázisok, fájlrendszer, eszköz szenzorok, rendszerszolgáltatások (LocationManager, Camera, Bluetooth). Ezek közvetlen használata lassú, törékeny és környezetfüggő teszteket eredményez. A Google Testing Blog (2023) szerint a jól elkülönített egységtesztek ezredmásodpercek alatt futnak, az integrációs tesztek pedig másodpercek és percek alatt.

A Test Doubles öt típusa

Gerard Meszaros osztályozása öt típusú Test Doubles-t foglal magában, amelyek viselkedésük és használati céljuk alapján különböznek. A köztük lévő különbségek megértése a helyes egységtesztelés alapja.

Dummy

Dummy — egy objektum, amelyet a tesztelt metódusnak adunk át, de soha nem használunk. A Dummy csak a metódus aláírásának kielégítéséhez szükséges. Kotlinban ez gyakran null, emptyList() vagy egy objektum helyettesítőkkel. A Dummy nem tartalmazhat semmilyen logikát — ha meghívásra kerül, a tesztnek meg kell buknia.

Fake

Fake — egy interfész egyszerűsített, de működő implementációja. A Mock-tól és Stub-tól eltérően a Fake valós üzleti logikát tartalmaz, de egyszerűsített formában. A klasszikus példa — InMemoryUserRepository, amely adatokat HashMap-ben tárolja adatbázis helyett. A Fake akkor használatos, amikor az állapotfüggő logikát kell tesztelni, de a valós infrastruktúra túlterhelése nélkül.

TípusCélPélda
DummyParaméter kitöltésenull, üres objektum
FakeMűködő egyszerűsített implementációInMemoryRepository
StubRögzített érték visszaadásawhen(api.getUser()).thenReturn(user)
SpyHívások rögzítése ellenőrzéshezverify(spy).save(user)
MockInterakció ellenőrzéseverify(mock).sendEmail(email)

Stub

Stub előre meghatározott értékeket ad vissza bizonyos hívásokra. A Stub nem ellenőrzi, hogy meghívták-e — csak adatokat szolgáltat. Mockito-ban a Stub a when(method).thenReturn(value) segítségével jön létre. A Stub ideális tesztelésre, amikor a függőségnek egy adott értéket kell visszaadnia, de maga a hívás ténye nem számít.

Spy

Spy — egy burkoló egy valós objektum körül, amely rögzíti az összes hívást későbbi verifikációhoz. A Mock-tól eltérően a Spy átirányítja a hívásokat a valós objektumhoz, de lehetővé teszi annak ellenőrzését, hogy azok megtörténtek. Mockito-ban a Spy a spy(realObject) segítségével jön létre. A Spy részleges mocking-hoz hasznos, amikor egy valós objektumot szeretnénk használni, de néhány hívást ellenőrizni szeretnénk.

Mock

Mock — egy objektum előre meghatározott hívási elvárásokkal. A Mock ellenőrzi, hogy bizonyos metódusokat bizonyos argumentumokkal és bizonyos sorrendben hívtak-e meg. A Stub-tól eltérően a Mock a viselkedés verifikációjára összpontosít, nem az adatok visszaadására. A Mock a legerősebb és leggyakrabban használt Test Double típus a mobil fejlesztésben.

Mock és Stub: fő különbségek

A Mock és Stub közötti különbség gyakran okoz zavart még tapasztalt fejlesztők körében is. A fő különbség a célban van: a Stub állapotot ellenőriz (state verification), a Mock viselkedést ellenőriz (behavior verification).

A Stub arra a kérdésre válaszol: „a kód a megfelelő eredményt adta vissza?“. A Mock arra a kérdésre válaszol: „a kód a megfelelő metódusokat hívta meg a megfelelő argumentumokkal?“. A mobil fejlesztésben a Stub akkor használatos, amikor az eredmény számít (pl. adatok a repozitóriumból), a Mock pedig amikor a mellékhatások számítanak (pl. email küldése, adatbázisba írás).

kotlin
// Stub: állapot ellenőrzése
every { repository.getUsers() } returns listOf(user)
val result = useCase.getUsers()
assertEquals(1, result.size)

// Mock: viselkedés ellenőrzése
every { analytics.logEvent("purchase") } returns Unit
useCase.purchase(item)
verify { analytics.logEvent("purchase") }

Test Doubles példák Kotlinban

Gyakorlati példák mind az öt típusú Test Doubles-re Kotlinban a MockK — a legnépszerűbb mocking könyvtár Android projektekhez — használatával.

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 teszt

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: fix API válasz visszaadása
        coEvery { api.register("test@test.com") } returns AuthResult.Success("token123")

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

        // Verify: annak ellenőrzése, hogy a felhasználó el lett mentve
        verify { repo.save(any()) }
        assertTrue(result.isSuccess())
    }
}

Dummy: teszt nem használt paraméterrel

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

fun `test logger with dummy context`() {
    // Dummy: Context nem használatos a Logger-en belül
    val dummyContext = mockk<Context>()
    val logger = Logger(dummyContext, FormatType.JSON)
    assertEquals(FormatType.JSON, logger.format)
}

Mikor melyik típust használjuk a mobil fejlesztésben

A Test Double típus kiválasztása attól függ, hogy pontosan mit tesztelünk: állapotot, viselkedést vagy integrációt. Android és iOS mobil fejlesztésben az alábbi ajánlások alakultak ki.

ViewModel és UseCase esetén

ViewModel tesztelésekor használjon Mock-ot a mellékhatásokat okozó függőségekhez (repozitóriumok, analitika, navigáció) és Stub-ot az adatokat visszaadó függőségekhez (API kliensek, ContentProvider). Ez lehetővé teszi annak ellenőrzését, hogy a ViewModel helyesen kezeli mind a sikeres, mind a hibás forgatókönyveket.

Repository és Adatréteg esetén

A Repository szintjén a Fake (in-memory adatbázis implementációk) és a Stub (fix API válaszok) előnyben részesülnek. A Fake lehetővé teszi a gyorsítótár logika és offline mód tesztelését SQLite konfiguráció nélkül. A Stub különböző HTTP állapotokat szimulál: 200, 404, 500, timeout.

  • Üzleti logika egységtesztjei — Mock az összes külső függőséghez, Dummy a nem használt paraméterekhez
  • Integrációs tesztek — Fake a Mock helyett (ellenőrizzük, hogy a komponensek együtt működnek)
  • UI tesztek — Stub az API válaszokhoz (MockWebServer vagy WireMock segítségével)
  • Gyorsítótár tesztek — Fake az adatbázishoz (in-memory a Room/SQLite helyett)
  • Aszinkron tesztek — Mock korutin támogatással (MockK + Turbine Flow-hoz)

Gyakori hibák a helyettesítők használatakor

A Test Doubles helytelen használata — az egyik leggyakoribb oka a törékeny teszteknek, amelyek minden átalakításnál elromlanak.

Over-mocking: Mock túlzott használata

A leggyakoribb hiba — mindennek a mockolása. Ha egy tesztben minden függőséget Mock helyettesít, a teszt megszűnik ellenőrizni a valós viselkedést. Mock csak külső függőségekhez használatos (hálózat, adatbázis, fájlrendszer, rendszerszolgáltatások). Az alkalmazás belső komponenseit (Value Object, data class, egyszerű segédprogramok) nem szabad helyettesíteni.

Under-specification: elégtelen specifikáció

A második hiba — Mock létrehozása az elvárások meghatározása nélkül. Ha egy metódust every / when nélkül hívunk meg, a Mock alapértelmezett értéket ad vissza (null, 0, false). Ez hamis pozitív tesztekhez vezethet, amikor a Mock néma null-t ad vissza, és a teszt ezt helyes viselkedésként értelmezi.

Over-verification: túlzott verifikáció

A harmadik hiba — minden Mock minden hívásának ellenőrzése. A Verify-t csak az üzleti logika szempontjából kritikus hívásokhoz szabad használni. A túlzott verifikáció törékennyé teszi a teszteket: a hívások sorrendjének megváltozása a termelési kódban viselkedésváltozás nélkül töri el a teszteket.

Gyakran ismételt kérdések

Mi a különbség a Mock és a Stub között?

Stub adatokat ad vissza és állapotot ellenőriz (mi lett visszaadva), míg Mock viselkedést ellenőriz (mely metódusok lettek meghívva). Stub = „ad vissza X“, Mock = „ellenőrizd, hogy Y meghívásra került Z argumentummal“. Valós tesztekben egy objektum gyakran egyszerre tölt be Stub és Mock szerepet.

Mikor használjunk Fake-t a Mock helyett?

A Fake előnyben részesítendő a Mock-kal szemben, amikor állapotfüggő logikát tesztelünk: gyorsítótár, offline mód, tranzakciók. A Fake (in-memory implementáció) lehetővé teszi e forgatókönyvek tesztelését törékeny verify hívások nélkül. A Mock alkalmasabb az adatküldés ellenőrzésére: analitika, push értesítések, email.

Melyik Test Doubles könyvtár jobb Androidra?

Kotlin Android projektekhez a MockK ajánlott. Támogatja a korutinokat, suspend függvényeket, sealed class-okat és extension függvényeket külön konfiguráció nélkül. Java projektekhez továbbra is a Mockito a szabvány — a legnépszerűbb könyvtár kiterjedt dokumentációval.

Hogyan teszteljük a Kotlin Flow-t Test Doubles-szel?

A Kotlin Flow teszteléséhez használja a Turbine könyvtárat a MockK-val együtt. A Turbine leegyszerűsíti a Flow emissziójának ellenőrzését: ellenőrizhető az értékek sorrendje, az áramlás befejeződése és a kivételek. A Stub Flow esetén flowOf(value) értéket ad vissza, a Mock ellenőrzi, hogy a Flow összegyűjtésre került.

Használhatók a Test Doubles UI tesztekben?

Igen, de az API válaszok szintjén, nem a UI komponensekén. A MockWebServer (OkHttp) és WireMock könyvtárak lehetővé teszik a HTTP válaszok helyettesítését UI tesztekben. Maguk a UI komponensek (Compose, SwiftUI Views) nem helyettesítendők — viselkedésük screenshot tesztekkel és Espresso-val tesztelendő.

Összefoglaló

  • Test Doubles — átfogó kifejezés öt típusú helyettesítő objektumra: Mock, Stub, Fake, Spy, Dummy
  • Mock viselkedést ellenőriz (verify), Stub adatokat ad vissza (thenReturn), Fake — egyszerűsített valós implementációként működik
  • Spy burkolja a valós objektumot és rögzíti a hívásokat, Dummy kitölti a nem használt paramétereket
  • Gerard Meszaros tipológiája — kanonikus osztályozás, amelyet minden modern mocking keretrendszer használ
  • Kotlin projektekhez MockK, Java-hoz Mockito, iOS-hez Cuckoo vagy OHHTTPStubs ajánlott
  • Gyakori hibák: over-mocking (mindennek helyettesítése), under-specification (meghatározatlan elvárások), over-verification (túlzott ellenőrzés)
  • Fake előnyben részesül a Mock-kal szemben állapotot tartalmazó logika tesztelésekor — gyorsítótár, offline mód és tranzakciók

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is