Ünite testi için bağımlılık enjeksiyonu gerekli midir?


55

Kullanıyor bağımlılık enjeksiyon ünitesi testi için (DI) olmazsa olmaz olan?

Kod yalıtımı için başka bir alternatif düşünemiyorum, bu yüzden test edilebilir. Ayrıca, şimdiye kadar gördüğüm tüm örnekler bu modeli kullanıyor. Bunun tek geçerli seçenek olması mı yoksa başka alternatifler mi var?


5
Bağımlılık Enjeksiyonu zorunlu değildir, ancak daha geniş bir Inversiyon Kontrolü kavramıdır.
Jeremy Heiler

Buradaki ölçek için söylenecek bir şey var. Çok az katman içeren küçük bir kod tabanım varsa, DI yararlı olmayabilir.
JB King,

@JBKing küçük bir kod tabanınız varsa katmanlara veya birim testine ihtiyacınız yok
Sklivvz

1
Kodunuzu test edilebilir hale getirmek için birçok tasarım kararı gerekir. Test yazmaya başla ve öğren.
Nathan Cooper,

Yanıtlar:


42

DI, birim testini çok daha kolaylaştırır. Ancak yine de DI olmadan birim testleri yazabilirsiniz. DI yaygınlaşmadan önce çok sayıda birim testi yazıldı. (Tabii ki, bu kullanılan tekniklerin bazıları, bir fantezi adı olduğunu bilmeden DI ile aynı veya çok benzer.

Ben kendim de DI hakkında bilgi edinmeden önce arayüzleri ve fabrikaları çok kullandım. Gerçek fabrika sınıfı adı, bir yapılandırma dosyasından okunmuş veya SUT'a bir argüman olarak geçirilmiş olabilir.

Başka bir yaklaşım, tekilleri (veya genel olarak genel olarak erişilebilir veri) kullanmaktır. Evet, genel olarak pek çok kişi tarafından (kendim dahil) önerilmediğini biliyorum. Yine de , özellikle, eğer singleton, test senaryosuna özgü olmayan, ancak üretim ile test ortamı arasında farklılık gösteren statik konfigürasyon verileri içeriyorsa, uygulanabilir olabilir . Elbette bilinen problemleri var, yani eğer kullanabilirseniz DI üstündür. Ancak sıklıkla (örneğin eski sistemlerde) yapamazsınız.

Bunlardan bahsedersek, Eski Kodla Etkili Bir Şekilde Çalışmak , testlerin kapsadığı eski kodları almak için birçok püf noktası açıklar. Bunların çoğu hoş değildir ve uzun vadeli bir çözüm olarak değildir. Ancak, yeniden yapılanmaya başlamanıza olanak tanıyan başka bir dengesiz sistem için ilk değerli birim testlerini yaratmanıza izin veriyorlar ve sonunda (diğerleri arasında) DI'yi tanıtıyorlar.


Kabul, DI özellikle alaycı nesneler için yararlıdır. Ancak DI'nin testlerde faydasız olduğu birçok senaryo vardır.
Kemoda

@Kemoda örneğin ne gibi?
BЈовић

@ VJovic Örneğin bağımsız nesneler. Bazı argümanlar alan ve bazı şeyler yapan bir yöntem düşünüyorum ama başka bir bileşene bağlı değil (dolayısıyla DI'ye gerek yok).
Kemoda

@Kemoda Fonksiyonel programlamayı tarif ediyor gibisiniz ve DI kullanıyorsunuz. Bağımlılıklarınızı yöntem parametreleri olarak enjekte ediyorsunuz.
Erik Dietrich

3
@ huggie, neden uygulama detayları burada sızdırılıyor? Enjekte edilen bağımlılık tipik olarak bir ara yüzün arkasına gizlenir ve asıl mesele, müşteri sınıfının bu bağımlılığın fiili uygulanmasının gerçek bir üretim sınıfı mı yoksa sahte mi olduğu hakkında hiçbir fikri olmadığı - ve ilgilenmediğidir. Başlaması, müşteri sınıfının dışında gerçekleşir, yalnızca hazır örneği görür.
Péter Török,

56

Ünite testi için dekuplaj gereklidir. DI, ayrıştırmayı başarmanın harika bir yoludur.


17
Soruyu hiçbir şekilde yanıtlamayan çok doğru bir ifade.
Travis,

10

Kullanmakta olduğunuz teknolojilere bağlı olarak, bağımlılıkları DI kullanmadan izole edebilirsiniz. Örneğin, .NET dünyasında, Moles bağımlılıkları DI modeli olmadan izole etmenize izin verir.

Bununla birlikte, bu izolasyon çerçevelerinin, dış bağımlılıklar (dosya sistemi, veritabanı, vb.) Kodunuzdaki durumlar için yazılmış ve amaçlanmış olduğuna inanıyorum. Bu, birinin bunu yapabileceği gerçeği, yapması gerektiği anlamına gelmez.

Bağımlılık enjeksiyonu birim testine izin verir, fakat aynı zamanda nesnenin kodunu değiştirmeden bir nesnenin davranışını değiştirmeye izin verir (açık / kapalı prensibi). Yani, sadece test edilebilir bir kod değil, aynı zamanda ortaya çıkan esnek bir koddur. Genelde, sürdürülebilir / esnek kod ile test edilebilir kod arasında ağır bir korelasyon olduğunu buldum.


3
Veya Moles, temiz, iyi faktörlü test edilebilir kodlara sahip olduğunuzu düşünmenizi sağlar çünkü büyü ile test ediyorsunuz.
Wyatt Barnett

@WyattBarnett Evet, çok doğru. Moles, birinin “bu polimorfizme ve açık / kapalı şeylere kim ihtiyacı var ki ?!” diyebilmesi için uyandırma kabiliyetine sahip bir yeteneği var.
Erik Dietrich

1
Mol'ler sahte numaralarla değiştirildi ve sahte sayfasından “Fakes çerçevesi geliştiricilerin birim testlerinde yapay uygulamalar yaratmalarına, uygulamalarına ve uygulamalarına enjekte etmelerine yardımcı oluyor” Bana öyle geliyor.
İşaret

1
@ İmzalı Bağlantınız ayrıca “Fakes çerçevesi, mühürlü türlerde sanal olmayan ve statik yöntemler de dahil olmak üzere herhangi bir .NET yöntemini kullanmak için kullanılabilir” diyor. İzolasyon çerçeveler DI ile birlikte kullanılabilir olması onlar anlamına gelmez vardır DI.
Erik Dietrich

4

Hayır, DI birim testi için şart değildir, ancak çok yardımcı olur.

Fabrikaları veya yer belirleyicileri kullanabilir ve DI ile yaptığınız gibi test edebilirsiniz (sadece bu kadar şık değil ve daha fazla kurulum gerektirir).

Ayrıca, Mock Objects , birçok çağrının bağımlılıklar yerine işlevlere atandığı eski sistemlerde önemli olacaktır. (Sahte Nesneler de uygun bir kurulumda da yaygın olarak kullanılabilir)

Testlerin neredeyse imkansız olduğu yerler olabilir. Ancak bu bağımlılık enjeksiyonunun kullanılıp kullanılmamasına dayanmamaktadır.


3

Hayır , birim enjeksiyon için bağımlılık enjeksiyonu şart değildir.

Bağımlılık enjeksiyonu, bazı alt işlemleri yapmak için bağımlı bir sınıf örneğine ihtiyaç duyan bir sınıfınız varsa yardımcı olur. DI yerine, bir iş yönteminin mantığını veri toplama kısmına (ünite test edilebilir olmayan) ve ünite test edilebilecek bir hesaplama kısmına ayırabilirsiniz.

Örnek (DI kullanarak) Bu uygulama Çalışan, Hesap, ...

 bool hasPermissionToTransferMoney(Employee employee, Account from, Account to, Money amount)
 {
     if (amount > 100 && employee.isStudent())
        return false;
     if (to.getOwner().getFamiliyName() == employee.getFamilyName() && ...
        return false; // cannot transfer money to himself;
     ...
 }

Veri toplama ve hesaplama işleminden sonra:

 bool hasPermissionToTransferMoney(Employee employee, Account from, Account to, Money amount)
 {
     return hasPermissionToTransferMoney(employee.isStudent(), employee.getFamilyName(), to.getOwner().getFamilyName(), ...);
 }

 // the actual permission calculation
 static bool hasPermissionToTransferMoney(boolean isStudent, string employeeFamilyName, string receiverFamilyName, ...)
     if (amount > 100 && isStudent)
        return false;
     if (receiverFamilyName == employeeFamiliyName && ...
        return false; // cannot transfer money to himself
     ...
 }

Hesaplama kısmı bağımlılık enjeksiyonuna gerek kalmadan kolayca test edilebilir.


1
  • Birim testi için bağımlılık enjeksiyonu şart değildir

  • Bir taraftan diğerine geçmek istediğinizde kontrolün tersine çevrilmesi esastır.


0

Evet, izolasyon için DI kullanımının alternatifleri vardır.

Alternatiflerden biri, gerçek nesneler yerine sahte nesneleri döndürmek için yapılan testlerden yapılandırılabilen fabrika veya ServiceLocator kullanmaktır.

Diğer bir uygun bir yalıtım çerçevesi veya alaycı bir araç kullanmaktır. Bu tür araçlar hemen hemen her modern programlama dili için var (Java, C #, Ruby ve Python için, en azından). Test edilen sınıf doğrudan bağımlılıklarını başlatsa bile, test edilen bir sınıfı diğer sınıfların / türlerin uygulanmasından izole edebilirler.

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.