Ana içeriğe geç

Yan yana

MockingvsTest Stub

Mock ile stub arasındaki fark nedir?

Güncellendi 3 dk okuma7 fark

Kısaca

Stub, test edilen kod çalışabilsin diye hazır yanıtlar döndürür; mock ise nasıl çağrıldığını da denetler ve beklenen çağrılar olmazsa test başarısız olur.

Mocking

Mocking, kodu yalıtılmış biçimde test etmek için veritabanı ya da API gibi gerçek bir bağımlılığı kontrol ettiğiniz bir sahteyle değiştiren test tekniğidir.

Mocking sayfasını oku

Test Stub

Test stub, gerçek bir bağımlılığın yerine geçip test sırasında hazır yanıtlar döndüren nesnedir; böylece kod gerçek veritabanı veya servis olmadan test edilir.

Test Stub sayfasını oku

Mocking ve Test Stub karşılaştırması

ÖzellikMockingTest Stub
AmacıKodun doğru çağrıları yaptığını denetlerKodun çalışması için gereken veriyi sağlar
Testin doğruladığıMock'a yapılan çağrılar: hangileri, kaç kez, hangi argümanlarlaTest edilen kodun sonucu ya da durumu
Doğrulama biçimiDavranış doğrulama (behavior verification)Durum doğrulama (state verification)
Testi başarısız kılabilir miEvet; beklenen çağrılar eksik ya da yanlışsaHayır; yalnızca yanıt döndürür
Uygulamaya bağlılıkDaha yüksek: kodun çalışma biçimini değiştirmek testi bozabilirDaha düşük: yalnızca sonuç denetlenir
Tipik kullanımYan etkili komutlar: e-posta göndermek, karttan ödeme almak, olay yayımlamakSorgular: bir döviz kuru, bir kullanıcı kaydı, güncel tarih, bir hata
KütüphanelerdeJest'te toHaveBeenCalledWith, Mockito'da verify(...)Jest'te mockReturnValue, Mockito'da when(...).thenReturn(...)

Fark, açıklamalı

Mock ve stub, ikisi de test double'dır: veritabanı, ödeme API'si ya da sistem saati gibi gerçek bir bağımlılığın yerine geçen ve testi hızlı ve öngörülebilir kılan vekillerdir. Stub yalnızca yanıt sağlar: kod bir döviz kuru istediğinde 0,9 döndürür, test de ardından kodun bu değerle ne yaptığını kontrol eder. Mock da yanıtlarla programlanır, ama ayrıca çağrılarını kaydeder ve onlara dair beklentiler taşır; örneğin sendEmail metodunun doğru adresle bir kez çağrılması gibi.

Asıl fark, testin neyi doğruladığıdır. Stub kullanıldığında test, test edilen kodun sonucunu ya da durumunu doğrular; Martin Fowler buna durum doğrulama (state verification) der ve stub tek başına bir testi asla başarısız kılmaz. Mock kullanıldığında ise test etkileşimin kendisini doğrular; Fowler buna davranış doğrulama (behavior verification) der ve e-posta göndermek ya da bir karttan ödeme almak gibi sonucu bir çağrı olan durumları denetlemenin tek yolu budur. Bugün en çok kullanılan terimler Gerard Meszaros'un 2007 tarihli xUnit Test Patterns kitabından gelir; kitap beş tür test double tanımlar: dummy, stub, spy, mock ve fake.

Çoğu test paketi ikisini birlikte kullanır, kütüphaneler de adları bulanıklaştırır. Jest, Sinon, Mockito ve Python'ın unittest.mock modülü, ikisi gibi de davranabilen nesneler oluşturur: mockReturnValue ya da when(...).thenReturn(...) bir stub oluşturur, toHaveBeenCalledWith ya da verify(...) ile doğrulama yapmak ise onu bir mock'a dönüştürür. Yaygın bir kalıp, kodun ihtiyaç duyduğu sorguları stub'lamak ve yalnızca çağrılması testin asıl konusu olan tek bir komutu mock'lamaktır.

Sık yapılan bir yanlış, her sahte nesnenin bir mock olduğu düşüncesidir. Her şeye mock demek asıl önemli seçimi gizler: çağrıları denetlemek testi kodun nasıl çalıştığına bağlar; bu yüzden davranış değişmese bile uygulama değiştiğinde test bozulur. Yalnızca sonuç önemliyse stub'ları tercih edin, mock'ları ise kendisi bir gereksinim olan etkileşimlere saklayın.

Hangisini kullanmalısınız?

Mocking şu durumlarda doğru seçim:

  • Önemsediğiniz sonuç, e-posta göndermek gibi başka bir sisteme yapılan bir çağrı.
  • Denetlenecek bir dönüş değeri ya da durum yok, yalnızca bir yan etki var.
  • Bir şeyin olmadığını kanıtlamanız gerekiyor; örneğin bir karttan iki kez ödeme alınmadığını.

Test Stub şu durumlarda doğru seçim:

  • Test edilen kod yavaş, maliyetli ya da güvenilmez bir bağımlılıktan veri istiyor.
  • Bir hata, bir zaman aşımı ya da boş bir liste gibi belirli bir yanıtı taklit etmek istiyorsunuz.
  • Yalnızca sonuç önemli ve test yeniden düzenlemelerden (refactoring) sağ çıkmalı.

Aynı Jest araçları, bir kez mock, bir kez stub olarak

Mockingjavascript
// Mock: the test checks how the dependency was called
test("sends a welcome email", async () => {
  const mailer = { send: jest.fn() };

  await registerUser({ email: "ada@example.com" }, mailer);

  expect(mailer.send).toHaveBeenCalledTimes(1);
  expect(mailer.send).toHaveBeenCalledWith("ada@example.com", "Welcome!");
});
Test Stubjavascript
// Stub: the dependency only returns a canned answer
test("converts dollars to euros", () => {
  const rates = { getRate: jest.fn().mockReturnValue(0.9) };

  const result = toEuros(100, rates);

  expect(result).toBe(90); // the test checks the result, not the calls
});

Sık sorulan sorular

Stub bir mock türü müdür?

İkisi de testlerde kullanılan her türlü vekil için genel terim olan test double'ın türleridir. Birçok kütüphane her double'a mock der; ama kesin anlamıyla stub yalnızca yanıt döndürür, mock ise çağrılarını da doğrular.

Mock ile spy arasındaki fark nedir?

Spy nasıl çağrıldığını kaydeder ve test bu çağrıları sonradan denetler; klasik bir mock ise önceden beklentilerle kurulur ve onları kendisi doğrular. Jest'te ve Sinon'da ikisi neredeyse aynıdır; jest.spyOn ayrıca gerçek bir metodu, çalışmaya devam edecek şekilde sarabilir.

Mock mu kullanmalıyım, stub mı?

Stub'larla başlayın ve sonuçları doğrulayın; böyle testler yeniden düzenlemelerden sağ çıkar. Gönderilmesi gereken bir e-posta gibi çağrının kendisi gereksinim olduğunda mock kullanın ve kodun yalnızca iç adımları olan çağrıları denetlemekten kaçının.

Daha fazla

Ayarlar