Test Süreçlerinde Mock Server Kullanımı

1. Mock Server Nedir? 🌐
Mock server, test edilen sistemin konuştuğu gerçek servisleri taklit eden kontrollü bir test bileşenidir. Amacı “gerçek servisin aynısını yazmak” değildir; testin ihtiyaç duyduğu davranışı güvenilir, hızlı ve tekrarlanabilir şekilde üretmektir.
Mock server özellikle şu sorunları çözer:
• Dış servis kapalıyken testlerin bloklanmasını engeller.
• Aynı input için aynı output dönerek deterministik test sağlar.
• 500, 401, timeout, malformed response gibi negatif senaryoları güvenle üretir.
• Test verisini gerçek sistemlere bulaştırmadan izole eder.
• API contract kırılımlarını erken yakalamayı kolaylaştırır.
2. Ne Zaman Kullanılır, Ne Zaman Kullanılmaz? ⚖️
Mock server doğru yerde kullanıldığında çok güçlüdür; yanlış yerde kullanıldığında ise sahte güven üretir. En büyük hata, mock ile her şeyi yeşile boyayıp gerçek entegrasyonun hiç test edilmemesidir.
Kullanılması gereken yerler
• Dış servis bağımlılığı test akışını yavaşlatıyorsa.
• Üçüncü parti servis maliyetli, limitli veya erişimi kısıtlıysa.
• Hata senaryoları gerçek sistemde kolay üretilemiyorsa.
• CI/CD pipeline içinde hızlı ve izole regresyon isteniyorsa.
• UI testinde arka uç cevabı sabitlenmek isteniyorsa.
Kullanılmaması gereken yerler
• Gerçek entegrasyonun tamamen yerine geçmek için.
• Contract güncel değilse veya response gerçek sistemden kopmuşsa.
• Performans testi yaparken gerçek darboğazı saklayacaksa.
• Güvenlik, auth, network ve sertifika davranışları testin ana konusuysa
3. Temel Mimari 🏗️

Bu mimaride test runner önce mock server üzerinde beklentiyi tanımlar. Ardından SUT yani test edilen uygulama “gerçek dış servise değil”, “mock server endpointine” yönlendirilir. Test sonunda sadece HTTP status değil; request body, response body, log, DB kaydı, event veya UI çıktısı da doğrulanır.
4. Adım Adım Kurulum Yaklaşımı 🛠️
Aşağıdaki yaklaşım araç bağımsızdır. WireMock, MockServer, Hoverfly veya kendi lightweight fake servisinizle uygulanabilir. Kritik nokta araç değil, test disiplinidir.
Adım 1 — Bağımlılıkları listele
Önce SUT’un hangi dış servislere gittiğini çıkar. Her servis için endpoint, method, auth yöntemi, request/response formatı, hata kodları ve timeout davranışı net olmalı.
Adım 2 — Test senaryolarını davranışa göre böl
Mock response’ları rastgele üretme. Her response bir test amacına hizmet etmeli: başarılı akış, eksik veri, geç cevap, 500 hata, 401 auth hatası, boş liste, duplicate kayıt gibi.
Adım 3 — Stub dosyalarını versiyonla
Stub (Önceden tanımlanmış sabit cevap taslağı) dosyalarını versiyonlayın. Bu dosyalar, Mock Server’ın hangi isteğe hangi hazır cevabı döneceğini belirleyen veri setleridir.
Adım 4 — Test başlamadan mock’u ayağa kaldır
Local geliştirme, CI pipeline ve nightly regression aynı komutla mock server başlatabilmeli. Docker Compose bunun için genellikle en pratik çözümdür.

Adım 5 — SUT konfigürasyonunu mock URL’ye çevir
Kod içinde URL değiştirmek pratik bir çözüm değil. Environment config, property dosyası veya pipeline variable kullanılabilir. Test ortamında dış servis base URL değeri mock server adresine gitmeli.

5. Örnek API Senaryosu 📝
Örnek senaryo: SUT, müşteri kampanya uygunluğunu kontrol etmek için dış bir campaign service çağırıyor. Gerçek servise gitmek yerine mock server üzerinden kontrollü cevap alıyoruz.

6. Mock Beklentisi Tanımlama 🎯
Aşağıdaki örnek, request path ve body içindeki customerId değerine göre response dönmeyi gösterir. Buradaki kritik fikir şudur: mock kuralı fazla gevşek olursa yanlış isteği de başarılı sanır; fazla katı olursa ufak format değişimlerinde gereksiz kırılır.

Pratik kural: request eşleşmesinde testin gerçekten önemsediği alanlar kontrol edilmeli. Her alanı ezbere assert etmek bakım maliyetini artırır; hiçbir alanı kontrol etmemek ise mock’u anlamsızlaştırır.
7. Otomasyon Testi İçinde Kullanım 🤖
Java + RestAssured kullanan bir framework’te mock server hazırlığı genellikle test öncesi hook çinde yapılır. Cucumber kullanılıyorsa @Before hook; TestNG kullanılıyorsa @BeforeMethod veya @BeforeClass uygun olabilir.


8. Negatif Senaryolar Ciddiye Alınmalı ⚠️

Sadece 200 OK dönen mock’larla test yazıyılıyorsa sahte konfor alanındasın. Gerçek sistemlerde problem yaratan şeyler genellikle latency, invalid data, auth problemi, rate limit ve beklenmeyen response formatıdır.

“Bu örnekle SUT’un timeout, retry veya fallback davranışı ölçülebilir. Ama dikkat: bu test yazılıp assertion koyulmazsa hiçbir anlamı yok. “Response geldi mi?” değil, “SUT gecikmeye doğru tepki verdi mi?” sorusu cevaplanmalı.”
9. Sequence Diagram: Testin Yaşam Döngüsü 🔄

Bu akışta testin kalitesi üç noktadan anlaşılır:
1- Mock beklentisi net mi ?
2-SUT gerçekten mock endpointi mi çağırıyor ?
3- Test sonunda sadece status code değil iş çıktısı da doğrulanıyor mu?
Bu üçünden biri eksikse test zayıf kalır.
10. CI/CD Pipeline Entegrasyonu ⛓️

Pipeline’da mock server kullanırken en sık yapılan hata temizlik adımını atlamaktır. Bir senaryodan kalan expectation diğer senaryoyu etkilerse flaky test üretilir. Her test suite başında mock resetlenmeli veya namespace mantığı kurulmalıdır.

11. Loglama ve Kanıt Toplama 📹
Mock server kullanılan testlerde request-response kanıtı şarttır. Çünkü hata olduğunda üç ihtimal vardır: test yanlış request üretti, mock yanlış eşleşti veya SUT beklenen davranışı göstermedi. Log yoksa bu üçlü arasında kör dövüşü yaşanır.
Toplanması gereken minimum kanıtlar
• Mock expectation ID veya stub adı.
• SUT’un attığı gerçek request path, header ve body bilgisi.
• Mock’un döndüğü status code ve response body.
• Assertion sonucu ve failure mesajı.
• CI build numarası ve environment bilgisi.

12. Contract Drift Riskini Yönet 🚨
Mock server’ın en büyük riski contract drift’tir. Yani “gerçek servis response formatı değişir ama mock eski kalır”. Testler yeşil görünür, prod entegrasyonu kırılır. Bu, mock kullanan ekiplerin en tehlikeli kör noktasıdır.
Bunu önlemek için:
• Mock response’ları gerçek contract veya OpenAPI şemasıyla eşleştir.
• Consumer-driven contract test yaklaşımını değerlendir.
• Haftalık veya nightly gerçek entegrasyon smoke testi koş.
• Stub dosyalarına sahiplik ata; herkesin rastgele değiştirdiği fixture çöplüğüne izin verme.
• Mock testleri ve gerçek entegrasyon testlerini raporda ayrı kategorileştir.
13. Önerilen Klasör Yapısı 📂

Bu yapı basit ama sürdürülebilir. Mock dosyaları feature dosyalarından ayrı durur, contract dosyaları görünür olur, test datası fixture ile karışmaz.
14. Best Practices ve Uygulama Prensipleri 🏆
• Her senaryo kendi mock hazırlığını yapmalı; gizli global state bırakma
• Test sonunda mock server resetlenmeli
• Response body gerçekçi olmalı; “foo: bar” tarzı veri ciddi testlerde çöp değerdedir
• Header, status code ve body birlikte doğrulanmalı
• Negatif senaryolar en az pozitif senaryolar kadar önemsenmeli
• Mock server ile geçen test, gerçek entegrasyonun geçtiği anlamına gelmez.
• CI’da mock başlatma hatası test hatası gibi görünmemeli; altyapı hatası olarak anlaşılmalı
• Mock fixture güncellemeleri code review’dan geçmeli
15. Sonuç 🏁
Mock server kullanımı, test otomasyonunda hız ve izolasyon sağlar; ama disiplinsiz kullanılırsa sistemi gerçekten test etmeyen sahte bir güven katmanına dönüşür. Doğru kullanımda ise dış bağımlılıkları kontrol altına alır, negatif senaryoları üretilebilir hale getirir ve CI/CD pipeline içinde daha güvenilir regresyon sağlar.