Birim Testi'nde neden iki kez bir Depo oluşturayım?


10

Geçen gün Birim Testi hakkında biraz okuyordum ve insanların bir depo arayüzü (yani IExampleRepository) oluşturdukları ve daha sonra gerçek depo ( public class ExampleRepository : IExampleRepository) ve birim testi ( FakeExampleRepository : IExampleRepository) için kullanılacak bir depo oluşturdukları bazı örnekler gördüm .

Gelen IExampleRepositoryonlar gibi aynı yöntemleri uygulayarak edildi ExampleRepositoryancak farklı Linq sorgu ile.

Buradaki amaç tam olarak nedir? Kod test biriminin bir parçası bir yöntemin doğru çalıştığından emin olduğunu düşündüm? Ama biri 'gerçek' diğeri testte olmak üzere iki farklı sorgu kullandığımda test ne kadar anlamlı?

Yanıtlar:


8

Birim testinin amaçlarından biri, tek seferde sadece bir şeyi, yani tek bir sınıfı ve yöntemi test etmektir. Havuzun kendisi test altında değilse, yöntem / sınıfınızdaki mantığı test etmek için normalde bunu bir şekilde alay edersiniz.

Bununla birlikte, 'gerçek' bir depo * ile test etmeniz gerektiğini söyler, ancak bu normalde bir entegrasyon / sistem testinde yapılır

* Açıkçası gerçek test için ayarlanmış repo gibi, umarım örneğin üretim DB.


Ünite testinde, doğru değerleri döndürdüğünden emin olmak için yöntemin kendisini test etmeyeceğim (sahte / alaycı veri kümesine göre)?
jao

Evet, yöntemin kendisini test edersiniz, ancak yalnızca yöntemdeki kod, diğer nesnelerdeki kod diğer birim testlerinde ele alınmalı, çoklu nesnelerin etkileşimi entegrasyon testlerinde veya daha yüksek seviye testlerinde ele alınmalıdır
jk.

1
Tamam, bu yüzden doğru anlarsam, depoları birim test ederken orijinal havuzu kullanmalıyım. Kontrolörler için birim testleri yazarken bunları test etmeme gerek yok (Asp.Net MVC durumunda)
jao

4
Bağlama @Theomax Bağlıdır: eğer test ünitesi olan bir yazılım bileşeni değil Şu Verilerinizi ExampleRepository, o zaman bir taklidini kullanmak en iyisidir. Gerekçe, depoyu birim olarak test etmemeniz, başka bir şeydir.
Andres F.8

5
@Theomax AndresF.'nin yorumunu genişletmek için: Birim testi yapıyorsanız ExampleRepository, gerçek olanı kullanın. Eğer birim test ise RepositoryController, o zaman gereken sadece bir kullanmak FakeExampleRepositorydonduğu önceden belirtilen değerleri. Bu şekilde, bir hata içeri girerse ExampleRepository, sadece bu birim testi başarısız olur - RepositoryControllertestleri başarılı olmaya devam eder, bu yüzden orada bir hata olmadığını bilirsiniz. Denetleyici gerçek depoyu kullansaydı, ikisi de başarısız olurdu ve 1 hata veya 2 olup olmadığını bilemezsiniz.
Izkata

5

Jk'nin iki cevabına katılıyorum. ve Jan Hudec - gerçekten iyi bilgiler veriyorlar. Ama biraz ekleyeceğimi düşündüm.

İlk sorunuz ("Buradaki amaç tam olarak nedir?") Önemlidir. Tanımladığınız durumda asıl amaç, IExampleRepositoryveri havuzu uygulamalarını test etmek değil , arayüzü kullanan sınıfları test etmektir. Oluşturmak, FakeExampleRepositorygerçek istemci sınıfının ayrıntıları hakkında endişelenmeden bu istemci sınıflarını test etmenizi sağlar.

Bu, özellikle kurmaya çalıştığınız nesne sınamayı zorlaştırıyorsa geçerlidir (örn. Dosya sistemine erişir, bir web hizmetini çağırır veya bir veritabanıyla konuşur). Arabirimler (ve benzeri teknikler) kullanarak kuplajı düşük tutarsınız. Bu nedenle, sınıfın Xyalnızca arayüz hakkında bilgi sahibi olması ve uygulama ayrıntılarını bilmesine gerek yoktur. Amaç, sınıfın Xdoğru şeyi yaptığından emin olmaktır .

Alaycı (ya da saplama, taklit etme ... nüanslı farklılıklar var) birim testi ve TDD için güçlü bir araçtır. Ancak bu uygulamaları manuel olarak oluşturmak ve sürdürmek acı verici olabilir. Bu nedenle, çoğu dilde yardımcı olacak alay kütüphaneleri var. C # kullandığınız için, basit ve çok güçlü olduğu için Moq'ı tavsiye ederim . Sonra sahte uygulamalar için ekstra kod yığmadan arabirime karşı test edebilirsiniz.


the real objective is to test the classes that are utilizing the IExampleRepository interfacebu kesinlikle doğru değil. Amaç IExampleRepository'den bağımsız olarak sınamaktır. İyi bir izolasyon çerçevesi önermek için +1.
StuperUser

1
Katılmıyorum. Bağımsız değildir IExampleRepositoryçünkü test altındaki sınıf bu arayüzle birleştirilir. Ancak arayüzün herhangi bir uygulamasından bağımsızdır . Açıklamamın muhtemelen biraz daha incelik kullanabileceğini kabul edeceğim. :)
Allan

5

Buradaki amaç tam olarak nedir?

İzolasyon.

Bir birimin fikri mümkün olan en küçük test etmek test birimi kodunun. Bunu , testteki diğer tüm üretim kodlarından ayırarak yaparsınız .

Sahte sınıflar oluşturarak tek üretim kodu test edilen sınıftır.

Sahte havuzu düzgün bir şekilde oluşturursanız ve test başarısız olursa, sorunun test altındaki kodla ilgili olduğunu bilirsiniz. Bu size ücretsiz teşhis avantajı sağlar.

Bu sahte ürünleri test koşullarını hızlı bir şekilde oluşturmak ve bunları iddia etmek için kullanmak için izolasyon çerçevelerine ( @Allan tarafından önerilen Moq gibi) bir göz atın .



4

Birim sınamasına sahte örnek sağlamak isteyebileceğiniz üç neden vardır:

  1. Testin kapsamını sınırlamak istiyorsunuz, böylece test depndee'deki hatalardan etkilenmeyecek, muhtemelen henüz bitmediği veya kararlı olmadığı veya başka birinin hatalarının testlerinizi etkilemesini istemediğiniz için.
  2. Dependee'nin kurulumu karmaşıktır. Örneğin veri erişim katmanı genellikle alay edilir, çünkü gerçek katman bir test veritabanı kurmayı gerektirir. Yine de gerçek veri erişim katmanını test etmeniz gerekir, ancak diğer şeylerde hata ayıklarken maliyetli kurulumu sınırlayabilirsiniz.
  3. Bağımlı sınıfın çeşitli hatalara düzgün tepki verdiğini sınamak için, her türlü yanlış yanıtı döndüren sahte bir sürüm sağlarsınız. Çünkü birçok arıza modunun çoğaltılması oldukça zordur, ancak yine de test edilmelidir.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.