Fake — nedir, amacı ve testte nasıl kullanılır

Yazar: IT Sectr Yayınlanma: 2026-04-10 Okuma süresi: 9 dk

Fake gerçek bir bileşen gibi davranan ancak üretim altyapısı yerine bellek içi depolama veya diğer hafif mekanizmaları kullanan bir bağımlılığın çalışan basitleştirilmiş uygulamasıdır. Stub'ın aksine, fake gerçek iş mantığı içerir — sıralama, filtreleme, toplama — ancak dış etkiler olmadan. Room yerine bellek içi veritabanı veya SharedPreferences yerine HashMap klasik örneklerdir. Daha fazla ayrıntı için Martin Fowler'ın test double sınıflandırmasına bakın.

Anahtar Noktalar

  • Fake — gerçek mantığa sahip ancak dış bağımlılıkları olmayan basitleştirilmiş çalışan uygulama
  • Bellek içi depolama — fake depo, veritabanı yerine HashMap'te veri saklar
  • Stub'dan farkı — stub sabit veri döndürür, fake çalıştırılabilir mantık içerir
  • Android — ViewModel ve UseCase'i test etmek için Fake olarak InMemoryUserRepository
  • iOS — gerçek sunucu yerine URLProtocol ve test verileriyle FakeNetworkSession

Fake nedir ve testte neden gereklidir?

Fake, test için uygun, bir arayüzün tam ancak hafif bir uygulamasıdır. Terim Gerard Meszaros (2007) tarafından “xUnit Test Patterns” kitabında tanıtılmıştır. Sabit kodlanmış yanıtlar döndüren stub'ın aksine, fake çalıştırılabilir kod içerir: bir listeyi sıralayabilir, koşula göre filtreleyebilir, kayıtları sayabilir. Üretim uygulamasından tek farkı, fake'in bellek içi verilerle çalışması ve gerçek G/Ç işlemleri gerçekleştirmemesidir.

Ana avantajı hızdır. Fake ile testler milisaniyeler içinde çalışır çünkü diske, ağa veya veritabanına erişim yoktur. Bellek içi bir HashMap, Room veya CoreData'dan 100–1000 kat daha hızlı çalışır. Aynı zamanda, fake gerçek iş mantığını test eder: sıralama, filtreleme, toplama — stub'ın test edemeyeceği her şey, çünkü stub yalnızca kendisine söyleneni döndürür. Fake, kodun önceden belirlenmiş bir yanıt almak yerine verileri doğru şekilde işlediği konusunda güven verir.

Fake Ne Zaman Stub'a Tercih Edilir

Fake, Stub'a tercih edilir — test edilen bileşen veriler üzerinde birden çok işlem gerçekleştiriyorsa (alma, filtreleme, sıralama, kaydetme), stub her çağrıyı ayrı ayrı yapılandırmayı gerektirir. Fake, mantığı kendi içinde barındırır — test basitçe yöntemleri çağırır ve sonucu kontrol eder. IT Sectr'da, birim testlerinde tüm depolar için fakes kullanırız: HashMap ile bir fake depo, Mockito veya MockK yapılandırmadan senaryoların %90'ını kapsar.

Fake vs Stub vs Mock: ne zaman ne seçilmeli

Seçim kriteri — testin neyi doğruladığını belirleyin: durum mu yoksa etkileşim mi. Test durumu (çalışmanın sonucu) doğruluyor ve mantık kullanıyorsa — fake kullanın. Testin yalnızca mantıksız girdi verisine ihtiyacı varsa — stub yeterlidir. Test bir yöntemin çağrıldığını doğruluyorsa — mock kullanın. Bir testte test double türlerini karıştırmak anlaşılmayı zorlaştırır ve kırılganlığı artırır.

KriterFakeStubMock
Mantığı varEvet (basitleştirilmiş)HayırHayır
HızYüksekMaksimumYüksek
Davranış doğrulamaDolaylıHayırEvet (verify)
BakımArayüz başına bir sınıfTest başına yapılandırTest başına yapılandır
GerçekçilikYüksek (kod çalışır)Düşük (sabit veri)Orta
Yanlış pozitif riskiDüşükOrtaYüksek (kırılgan testler)

Anti-kalıp: Fake olmayan fake — bir geliştiricinin aslında stub veya mock olan bir nesneye fake demesi yaygın bir hatadır. InMemoryUserRepository'iniz mantık (filtreleme, sıralama) içermiyorsa — bu fake değil, bellek içi depolamalı bir stub'dır. Fake, stub'dan tam olarak çalıştırılabilir mantığa sahip olmasıyla ayrılır. Bir fake depo yalnızca içine konulanı döndürüyor ve verileri işlemiyorsa — mock veya stub kullanın.

Test Double Seçimi için Pratik Kural

Pratik öneri — her depo veya hizmet için bir fake ile başlayın. Bir fake 50 satırı aşarsa — birkaç sınıfa bölün. Fake hiç gerekli değilse (test yalnızca sabit verili tek bir senaryoyu doğruluyorsa) — stub kullanın. Test bir yöntemin belirli parametrelerle çağrıldığını doğruluyorsa — mock kullanın. Seçimi önceden optimize etmeyin: bir fake yazın ve aşırı olduğu ortaya çıkarsa, belirli bir testte onu bir stub ile değiştirin.

Android'de Room ve Retrofit için Fake nesneleri oluşturma

Room için Fake depo — Android'de tipik bir fake örneği. UserRepository'nin üretim uygulaması SQLite sorgularıyla Room DAO kullanır. Fake sürüm, verileri bir MutableList veya HashMap'te saklar ve aynı yöntemleri uygular: getUser(id), saveUser(user), deleteUser(id). Fake, arama, filtreleme ve sıralama mantığı içerir — üretim deposuyla aynı, ancak SQL olmadan. Bu, Room veritabanı kurmadan ViewModel ve UseCase'i test etmeyi sağlar.

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)
        }
    }
}

Retrofit API için Fake — MockWebServer (bir stub'dır, fake değildir) yerine, bellek içi bir koleksiyondan veri döndüren bir ApiService uygulaması oluşturabilirsiniz. Farkı: MockWebServer HTTP'yi keser ve JSON döndürürken, fake ApiService serileştirme olmadan Kotlin arayüzü düzeyinde çalışır. Fake daha hızlıdır (JSON ayrıştırma yok) ve hata ayıklaması daha kolaydır (aynı süreçte çalışır, tür belirtilmiş). HTTP anlambiliminin (durum kodları, başlıklar) önemli olmadığı testler için uygundur.

Hızlı testler için FakeSharedPreferences

— başka bir yaygın senaryo. Üretim SharedPreferences'leri commit/apply aracılığıyla diske yazar. Fake sürüm, anahtar-değer çiftlerini bir HashMap'te saklar ve verileri anında döndürür. Aynı yöntemleri destekler: getString, putString, getInt, putInt, clear. Jetpack DataStore için benzeri, bellek içi depolamalı FakeDataStore'dır. Bu tür fakes, disk yazma işlemi olmadığı için testleri onlarca kat hızlandırır.

iOS'ta bellek içi depolama ile Fake uygulamaları

Swift'te Fake — protokoller aracılığıyla oluşturulur. Üretim sınıfı, protokolü gerçek mantıkla (CoreData, URLSession) uygular. Fake yapısı, aynı protokolü bellek içi depolama ve basitleştirilmiş mantıkla uygular. Swift, değer anlambilimine sahip bir dildir, bu nedenle fake yapıları değiştirilemez ve çok iç parçacıklı testlerde güvenlidir. Bu, Android benzerlerine göre bir avantaj sağlar: bellek içi verilere erişimi senkronize etmeye gerek yoktur.

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")
    }
}

CoreData için Fake — iOS projelerinde, description.type = NSInMemoryStoreType ayarını yaparak bellek içi bir NSPersistentContainer oluşturabilirsiniz. Bu, tam bir CoreData yığınıdır ancak bellekte çalışır. Böyle bir fake, SQLite dosyası oluşturmadan NSFetchRequest, koşullar ve sıralamaları test etmeye olanak tanır. Hız: bellek içi CoreData'daki testler, disk tabanlı benzerinden 5–10 kat daha hızlı çalışır. Dezavantajı: her seferinde NSManagedObjectModel kurulumu gerektirir.

FakeURLProtocol — iOS'ta ağ isteklerini kesmek için URLProtocol'un bir alt sınıfıdır. URLProtocol.registerClass(fakeProtocol) aracılığıyla kaydedilir. Dahili olarak bellek içi bir URL -> Data sözlüğü içerir ve gerçek istek olmadan veri döndürür. Stub'dan farkı: FakeURLProtocol istek gövdesini, başlıkları kontrol edebilir ve girdi verilerine bağlı olarak farklı yanıtlar döndürebilir. İstek yönlendirme mantığı içerdiği için bu bir fake'tir.

Mobil projelerde Fake kullanım kalıpları

Test Fixture olarak Fake — fake sınıflarını paylaşılan bir test modülüne (androidTest/sharedTest veya TestSupport) koyun. Projedeki tüm testler aynı InMemoryUserRepository'yi kullanır. Bu, her testte mock nesne kurulumunun tekrarını ortadan kaldırır ve tek tip davranışı garanti eder. Fake mantığını değiştirmek tüm testleri aynı anda günceller. IT Sectr'da, fake sınıflarını sharedTest/java/com/itSectr/fake/ içinde saklıyoruz ve bunları implementation project(:sharedTest) aracılığıyla dahil ediyoruz.

Önceden ayarlanmış verilerle Fake — testler genellikle zaten bazı kayıtları içeren bir depoya ihtiyaç duyar. Çözüm: bir fabrika yöntemi fakeWithData(vararg items) veya yerleşik bir addDefaultData() yöntemi. Fabrika bir fake oluşturur, tipik verilerle doldurur ve kullanıma hazır bir nesne döndürür. Bu, testlerdeki tekrarı azaltır: mock çağrılarını ayarlamak yerine, test basitçe FakeUserRepository.withUsers(alice, bob) çağrısını yapar.

Çağrı sayma ile Fake — bazen yalnızca durumu değil, aynı zamanda çağrı sayısını da doğrulamak gerekir. Fake, sayaçlar içerebilir: saveCallCount, getUserCallCount. Test, çalıştırmadan sonra sayacı kontrol eder. Bu, saf fake (durum doğrulama) ile mock (etkileşim doğrulama) arasında bir uzlaşıdır. Sayaçlar, bağımsız değişkenleri veya çağrı sırasını kontrol etmez — yalnızca sayıyı kontrol eder. Bağımsız değişken doğrulaması için mock kullanın.

Callback ile Fake — eş zamansız senaryoları test etmek için fake, her çağrıda bir callback kabul edebilir: beforeGetUser, afterSaveUser. Bu, gecikmeleri, hataları simüle etmeye veya ara durumları kontrol etmeye olanak tanır. Bu yaklaşım, UI yükleme durumlarını test etmek için kullanışlıdır: fake 100 ms duraklatır ve test, ekranın bir yükleyici gösterdiğini doğrular. Callback üretimde yoktur — bu tamamen test işlevselliğidir.

Sıkça Sorulan Sorular

Fake, Stub'dan nasıl farklıdır?

Fake işlevsel mantık içerir — filtreler, sıralar, sayar. Stub, mantıksız yalnızca önceden belirlenmiş yanıtlar döndürür. Bir nesnenin dallanmaları (if/else, when) varsa — bu fake'tir. Yalnızca dönüş değerleri içeriyorsa — bu stub'dır. Fake bakımı daha maliyetlidir ancak daha gerçekçi testler sağlar.

Bir fake ne zaman zararlı olabilir?

Fake mantığı üretim mantığıyla eşleşmediğinde. Örneğin, FakeUserRepository büyük/küçük harfe duyarlı arama kullanırken, üretim sürümü büyük/küçük harfe duyarsızdır. Test geçer ancak gerçekte bir hata vardır. Çözüm: fake mantığını ayrı ayrı test edin veya yalnızca basit mantığa (CRUD işlemleri) sahip arayüzler için fakes kullanın. Karmaşık mantık için gerçek bir veritabanıyla entegrasyon testleri yazın.

Fake, bellek içi veritabanıyla aynı şey midir?

Bellek içi veritabanı bir fake türüdür. Room.inMemoryDatabaseBuilder(), üretim veritabanı gibi davranan bellek içi SQLite oluşturur. Bu tam teşekküllü bir fake'tir. Ancak fake, depo düzeyinde (SQL olmadan) ve ağ düzeyinde (FakeApiService) de olabilir. Bellek içi veritabanı, mantığın gerçeğe mümkün olduğunca yakın olduğu özel bir fake durumudur.

Bir testte Fake ve Mock'u birleştirebilir miyim?

Evet, ancak dikkatli olun. Fake depo için (veri), Mock AnalyticsTracker için (olay doğrulama). Katmanlara göre ayırma: veri katmanı için fake, analitik/günlük katmanı için mock. Bir nesneyi aynı anda fake ve mock yapmayın — bu Tek Sorumluluk İlkesi'ni ihlal eder ve testi karıştırır.

Fake'in kendisini nasıl test ederim?

Fake'i test edin üretim uygulamasıyla aynı testlerle. save, get, delete'i doğrulayan bir UserRepositoryTest'iniz varsa — iki kez çalıştırın: FakeUserRepository ve RealUserRepository ile. Bu, fake'in üretim sınıfının davranışını tekrarladığını garanti eder. Fake farklı davranmaya başlarsa — test her iki uygulamada da başarısız olur.

Özet

  • Fake — gerçek iş mantığı ve bellek içi depolama ile bir bağımlılığın çalışan basitleştirilmiş uygulaması
  • Stub'dan farkı — fake mantık içerir (filtreleme, sıralama), stub yalnızca veri döndürür
  • Hız — fake, G/Ç işlemleri olmadan üretim uygulamasından 100–1000 kat daha hızlı çalışır
  • Android — InMemoryUserRepository, FakeDataStore, Room.inMemoryDatabaseBuilder ile bellek içi Room
  • iOS — protokol tabanlı fake, bellek içi CoreData, HTTP kesme için FakeURLProtocol
  • En iyi uygulama — fakes'i paylaşılan bir test modülüne koyun ve tüm proje testlerinde kullanın
  • Fake'i test edin — tutarlılığı doğrulamak için fake ve üretim uygulamasında aynı testleri çalıştırın

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun