Fake — mi ez, célja és hogyan használjuk tesztelésben

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

Fake (féjk) — egy működő egyszerűsített függőség-implementáció, amely úgy viselkedik, mint egy valódi komponens, de in-memory tárolást vagy más könnyű mechanizmusokat használ éles infrastruktúra helyett. A stub-bal ellentétben a fake valódi üzleti logikát tartalmaz — rendezést, szűrést, aggregálást — csak külső hatások nélkül. In-memory adatbázis Room helyett vagy HashMap SharedPreferences helyett — klasszikus példák. Bővebben Martin Fowler test doubles osztályozásában.

Főbb pontok

  • Fake — egyszerűsített működő implementáció valódi logikával, de külső függőségek nélkül
  • In-memory tárolás — a fake-adattár az adatokat HashMap-ben tárolja, nem adatbázisban
  • Különbség a Stub-tól — a stub rögzített adatokat ad vissza, a fake végrehajtható logikát tartalmaz
  • Android — InMemoryUserRepository Fake-ként a ViewModel és UseCase teszteléséhez
  • iOS — FakeNetworkSession URLProtocol-tal és tesztadatokkal valódi szerver helyett

Mi az a Fake és miért van rá szükség a tesztelésben?

Fake — egy teljes, de könnyű interfész-implementáció, amely alkalmas tesztelésre. A kifejezést Gerard Meszaros (2007) vezette be az «xUnit Test Patterns» című könyvben. A stub-bal ellentétben, amely szigorúan előre meghatározott válaszokat ad vissza, a fake végrehajtható kódot tartalmaz: képes rendezni egy listát, feltétel szerint szűrni, megszámolni a rekordokat. Az egyetlen különbség az éles implementációtól — a fake in-memory adatokkal dolgozik és nem végez valódi I/O-műveleteket.

Fő előny — sebesség. A fake-kel végzett tesztek milliszekundumok alatt futnak le, mert nincs hozzáférés a lemezhez, hálózathoz vagy adatbázishoz. Az in-memory HashMap 100-1000-szer gyorsabban működik, mint a Room vagy a CoreData. Ugyanakkor a fake ellenőrzi a valódi üzleti logikát: rendezést, szűrést, aggregálást — mindazt, amit a stub nem tud ellenőrizni, mert a stub csak azt adja vissza, amit neki mondtak. A fake biztosítja, hogy a kód helyesen dolgozza fel az adatokat, nem csak egy előre meghatározott választ kap.

Mikor jobb a Fake, mint a Stub

A Fake jobb, mint a Stub — ha a tesztelt komponens több műveletet végez az adatokon (kiolvasott, szűrt, rendezett, mentett), a stub minden hívást külön konfigurálást igényel. A fake a logikát tartalmazza — a teszt egyszerűen meghívja a metódusokat és ellenőrzi az eredményt. Az IT Sectr-ben minden adattárhoz fake-et használunk az egységtesztekben: a HashMap-es fake-adattár a forgatókönyvek 90%-át lefedi Mockito vagy MockK konfiguráció nélkül.

Fake vs Stub vs Mock: mikor mit válasszunk

Választási szempont — határozza meg, mit ellenőriz a teszt: állapotot vagy interakciót. Ha a teszt állapotot (a munka eredményét) ellenőrzi és logikát használ — fake szükséges. Ha a tesztnek csak bemeneti adatokra van szüksége logika nélkül — stub is elegendő. Ha a teszt egy metódus meghívásának tényét ellenőrzi — mock szükséges. A test doubles típusainak keverése egy tesztben megnehezíti a megértést és növeli a törékenységet.

SzempontFakeStubMock
Logika megléteIgen (egyszerűsített)NemNem
SebességMagasMaximálisMagas
Viselkedés ellenőrzéseKözvetettNemIgen (verify)
KarbantartásEgy osztály interfészenkéntKonfiguráció tesztenkéntKonfiguráció tesztenként
RealizmusMagas (kód működik)Alacsony (rögzített adatok)Közepes
Hamis riasztások kockázataAlacsonyKözepesMagas (törékeny tesztek)

Antiminta: Fake, ami nem fake — gyakori hiba, amikor a fejlesztő fake-nek nevez egy objektumot, ami valójában stub vagy mock. Ha az InMemoryUserRepository nem tartalmaz logikát (szűrést, rendezést) — ez nem fake, hanem stub in-memory tárolással. A fake éppen a végrehajtható logika jelenlétében különbözik a stub-tól. Ha a fake-adattár csak visszaadja, amit belehelyeztek, és nem dolgozza fel az adatokat — használjon mock-ot vagy stub-ot.

Gyakorlati szabály a test double kiválasztásához

Gyakorlati javaslat — kezdje fake-kel minden adattár vagy szolgáltatás esetén. Ha a fake 50 sornál összetettebb — ossza fel több osztályra. Ha a fake egyáltalán nem szükséges (a teszt csak egy forgatókönyvet ellenőriz rögzített adatokkal) — használjon stub-ot. Ha a teszt ellenőrzi, hogy egy metódust meghívtak-e bizonyos paraméterekkel — használjon mock-ot. Ne optimalizálja előre a választást: írjon fake-et, és ha túlzónak bizonyul, cserélje le stub-ra az adott tesztben.

Fake-objektumok létrehozása Androidon Room és Retrofit számára

Fake-adattár Room számára — tipikus példa fake-re Androidon. Az éles UserRepository implementáció Room DAO-t használ SQLite lekérdezésekkel. A fake verzió az adatokat MutableList-ben vagy HashMap-ben tárolja, és ugyanazokat a metódusokat implementálja: getUser(id), saveUser(user), deleteUser(id). A fake tartalmazza a keresési, szűrési és rendezési logikát — ugyanazt, mint az éles adattárban, de SQL nélkül. Ez lehetővé teszi a ViewModel és UseCase tesztelését a Room adatbázis konfigurálása nélkül.

kotlin
class FakeUserRepository : UserRepository {

    private val users = mutableListOf<User>()

    override suspend fun getUser(id: String): User? {
        return users.find { it.id == id }
    }

    override suspend fun saveUser(user: User) {
        val index = users.indexOfFirst { it.id == user.id }
        if (index >= 0) users[index] = user
        else users.add(user)
    }

    override suspend fun search(query: String): List<User> {
        return users.filter {
            it.name.contains(query, ignoreCase = true)
        }
    }
}

Fake Retrofit API-hoz — a MockWebServer (ami stub, nem fake) helyett létrehozható egy ApiService implementáció, amely in-memory gyűjteményből ad vissza adatokat. Különbség: a MockWebServer elfogja a HTTP-t és JSON-t ad vissza, míg a fake-ApiService a Kotlin interfész szintjén dolgozik szerializálás nélkül. A fake gyorsabb (nincs JSON-elemzés) és egyszerűbb hibakeresés (ugyanabban a folyamatban dolgozik, típusos). Alkalmas olyan tesztekhez, ahol a HTTP szemantika (státuszkódok, fejlécek) nem számít.

FakeSharedPreferences gyors tesztekhez

— máik gyakori forgatókönyv. Az éles SharedPreferences commit/apply segítségével ír a lemezre. A fake verzió kulcs-érték párokat tárol HashMap-ben és azonnal visszaadja az adatokat. Ugyanazokat a metódusokat támogatja: getString, putString, getInt, putInt, clear. Jetpack DataStore esetén az analóg FakeDataStore in-memory tárolással. Az ilyen fake-ek tízszeresére gyorsítják a teszteket, mert nincs lemezre írási művelet.

Fake-implementációk iOS-en in-memory tárolókkal

Fake Swift-ben — protokollokon keresztül épül fel. Az éles osztály valódi logikával (CoreData, URLSession) implementálja a protokollt. A fake struktúra ugyanazt a protokollt implementálja in-memory tárolóval és egyszerűsített logikával. A Swift értékszemantikájú nyelv, ezért a fake struktúrák megváltoztathatatlanok és biztonságosak többszálú tesztekben. Ez előnyt jelent az Android-analógokkal szemben: nem kell szinkronizálni az in-memory adatokhoz való hozzáférést.

swift
protocol UserRepositoryProtocol {
    func getUser(id: String) async -> User?
    func saveUser(user: User) async
}

final class FakeUserRepository: UserRepositoryProtocol {
    private var storage: [String: User] = [:]

    func getUser(id: String) async -> User? {
        return storage[id]
    }

    func saveUser(user: User) async {
        storage[user.id] = user
    }
}

final class UserViewModelTests: XCTestCase {
    func test_save_and_load() async {
        let fake = FakeUserRepository()
        let vm = UserViewModel(repository: fake)
        let user = User(id: "1", name: "Alice")

        await vm.saveUser(user)
        let loaded = await vm.getUser(id: "1")

        XCTAssertEqual(loaded?.name, "Alice")
    }
}

Fake CoreData-hoz — iOS-projektekben létrehozható egy in-memory NSPersistentContainer a description.type = NSInMemoryStoreType beállításával. Ez egy teljes CoreData stack, amely memóriában dolgozik. Az ilyen fake lehetővé teszi NSFetchRequest, predikátumok és rendezések tesztelését SQLite fájl létrehozása nélkül. Sebesség: az in-memory CoreData tesztek 5-10-szer gyorsabban futnak, mint a lemezes analóg. Hátrány: az NSManagedObjectModel-t minden alkalommal konfigurálni kell.

FakeURLProtocol — az URLProtocol alosztálya hálózati kérések elfogására iOS-en. Az URLProtocol.registerClass(fakeProtocol) segítségével regisztrálható. Belül egy in-memory URL -> Data szótárt tartalmaz, és adatokat ad vissza valódi kérés nélkül. Különbség a stub-tól: a FakeURLProtocol ellenőrizheti a kérés törzsét, fejléceket, és különböző válaszokat adhat vissza a bemeneti adatoktól függően. Ez fake, mert kérés-útvonalválasztó logikát tartalmaz.

Fake használati minták mobilprojektekben

Fake mint Test Fixture — helyezze át a fake osztályokat egy megosztott tesztmodulba (androidTest/sharedTest vagy TestSupport). A projekt összes tesztje ugyanazt az InMemoryUserRepository-t használja. Ez kiküszöböli a mock objektumok konfigurálásának megkettőzését minden tesztben és egységes viselkedést garantál. A fake logikájának változása az összes tesztet egyszerre frissíti. Az IT Sectr-ben a fake osztályokat a sharedTest/java/com/itSectr/fake/ könyvtárban tároljuk és az implementation project(:sharedTest) segítségével csatlakoztatjuk.

Fake előre beállított adatokkal — gyakran a teszteknek olyan adattárra van szükségük, amely már tartalmaz néhány rekordot. Megoldás: fakeWithData(vararg items) gyári metódus vagy beépített addDefaultData() metódus. A gyár létrehozza a fake-et, feltölti tipikus adatokkal és visszaadja a használatra kész objektumot. Ez csökkenti a boilerplate-et a tesztekben: a mock hívások konfigurálása helyett a teszt egyszerűen meghívja a FakeUserRepository.withUsers(alice, bob) függvényt.

Fake hívásszámlálással — néha nem csak az állapotot, hanem a hívások számát is ellenőrizni kell. A fake számlálókat tartalmazhat: saveCallCount, getUserCallCount. A teszt a számlálót ellenőrzi a végrehajtás után. Ez kompromisszum a tiszta fake (állapot ellenőrzése) és a mock (interakció ellenőrzése) között. A számlálók nem ellenőrzik az argumentumokat és a hívások sorrendjét — csak a számot. Az argumentumok ellenőrzéséhez használjon mock-ot.

Fake Callback-kel — aszinkron forgatókönyvek teszteléséhez a fake minden híváskor fogadhat egy callback-et: beforeGetUser, afterSaveUser. Ez lehetővé teszi késleltetések, hibák szimulálását vagy köztes állapotok ellenőrzését. Ez a megközelítés hasznos az UI betöltési állapotainak teszteléséhez: a fake 100 ms szünetet tart, és a teszt ellenőrzi, hogy a képernyő betöltőt mutat. Éles környezetben a callback nem létezik — ez tisztán tesztfunkcionalitás.

Gyakran ismételt kérdések

Miben különbözik a Fake a Stub-tól?

Fake működő logikát tartalmaz — szűr, rendez, számol. A Stub csak előre meghatározott válaszokat ad vissza logika nélkül. Ha az objektumnak elágazásai vannak (if/else, when) — ez fake. Ha csak return values-t tartalmaz — ez stub. A fake drágább karbantartani, de realisztikusabb teszteket ad.

Mikor lehet káros a fake?

Amikor a fake logikája nem egyezik az éles logikával. Például a FakeUserRepository case-sensitive keresést használ, míg az éles case-insensitive-t. A teszt átmegy, de a valóságban hiba van. Megoldás: tesztelje a fake logikáját külön, vagy használjon fake-eket csak egyszerű logikájú interfészekhez (CRUD-műveletek). Összetett logikához írjon integrációs teszteket valódi adatbázissal.

A Fake ugyanaz, mint az in-memory database?

In-memory database — a fake egyik változata. A Room.inMemoryDatabaseBuilder() egy in-memory SQLite-ot hoz létre, amely úgy viselkedik, mint egy éles adatbázis. Ez egy teljes fake. De a fake lehet adattár szinten (SQL nélkül) és hálózati szinten (FakeApiService) is. Az in-memory adatbázis a fake speciális esete, ahol a logika maximálisan közelít a valódihoz.

Lehet Fake és Mock kombinálni egy tesztben?

Igen, de óvatosan. Fake az adattárhoz (adatok), Mock az AnalyticsTracker-hez (események ellenőrzése). Rétegenkénti szétválasztás: fake az adatréteghez, mock az analitikai/naplózási réteghez. Ne tegyen egy objektumot egyszerre fake-é és mock-ká — ez sérti az egységes felelősség elvét és összezavarja a tesztet.

Hogyan teszteljük magát a Fake-et?

Tesztelje a fake-et ugyanazokkal a tesztekkel, mint az éles implementációt. Ha van UserRepositoryTest, ami ellenőrzi a save, get, delete függvényeket — futtassa kétszer: FakeUserRepository-val és RealUserRepository-val. Ez garantálja, hogy a fake megismétli az éles osztály viselkedését. Ha a fake máshogy kezd viselkedni — a teszt mindkét implementáción megbukik.

Összefoglaló

  • Fake — működő egyszerűsített függőség-implementáció valódi üzleti logikával és in-memory tárolással
  • Különbség a Stub-tól — a fake logikát tartalmaz (szűrés, rendezés), a stub csak adatokat ad vissza
  • Sebesség — a fake 100-1000-szer gyorsabban működik, mint az éles implementáció I/O-műveletek nélkül
  • Android — InMemoryUserRepository, FakeDataStore, in-memory Room Room.inMemoryDatabaseBuilder segítségével
  • iOS — protokoll-alapú fake, in-memory CoreData, FakeURLProtocol HTTP-elfogáshoz
  • Legjobb gyakorlat — helyezze át a fake-et egy megosztott tesztmodulba és használja a projekt összes tesztjében
  • Tesztelje a fake-et — futtassa ugyanazokat a teszteket a fake-en és az éles implementáción a konzisztencia ellenőrzéséhez

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