Birim Testi için IoC'yi Kullanma


97

Birim testi için bir IoC Container nasıl kullanılabilir? IoC kullanarak büyük bir çözümde (50'den fazla proje) taklitleri yönetmek faydalı mı? Herhangi bir deneyim? Birim testlerinde kullanmak için iyi çalışan herhangi bir C # kitaplığı?


7
@ Mark Seemann bunu işaret etmek çok mütevazı olurdu, ama bu soruya ilgileniyorsanız, en azından farkında olmalı AutoFixture
Ruben Bartelink

1
Miguel Castro'nun
Vimeo'da

Yanıtlar:


131

Genel olarak konuşursak, birim testi için bir DI Konteyner gerekli olmamalıdır çünkü ünite testi tamamen sorumlulukları ayırmakla ilgilidir.

Constructor Injection kullanan bir sınıf düşünün

public MyClass(IMyDependency dep) { }

Uygulamanızın tamamında, arkasında gizlenmiş büyük bir bağımlılık grafiği olabilir IMyDependency, ancak bir birim testinde hepsini tek bir Test Çiftine indirirsiniz .

Test Double'ı oluşturmak için Moq veya RhinoMocks gibi dinamik taklitler kullanabilirsiniz, ancak bu gerekli değildir.

var dep = new Mock<IMyDependency>().Object;
var sut = new MyClass(dep);

Bazı durumlarda, otomatik olarak alay edilen bir konteynıra sahip olmak güzel olabilir, ancak üretim uygulamasının kullandığı DI Konteyneri kullanmanıza gerek yoktur.


13
kabul edildi ... bir test hedefinin bağımlılık olarak bir IoC konteyneri içermediği sürece , testlerinizin bunlara ihtiyacı olmamalıdır ... birim testlerinizi yaparken nesne grafiğinin çoğunu kaldıracaksınız.
Anderson Imes

4
@Mark Seemann Bu mantıklı ... Peki ya entegrasyon testleri? Yani, UI testleri ile oynadım ve kompozisyon kökünü paylaşmam gerektiğinde durumla karşılaştım. Herhangi bir yorum?
Arnis Lapsa

5
@Arnis L .: Entegrasyon testleri için daha az önemli. Bileşenleri bağlamak için bir DI Konteyner kullanmayı seçebilirsiniz, ancak öyleyse, bir Subkutan Test veya tam Sistem Testi yapmadığınız sürece, konteyner için tam uygulamadakinden farklı bir konfigürasyona ihtiyacınız olacaktır. uygulamanın Konteyner yapılandırmasını yeniden kullanabilirsiniz.
Mark Seemann

msdn dergisine referans Test Double: download.microsoft.com/download/3/A/7/…
M.Hassan

18

Birim testi için bir Ioc Konteyner nasıl kullanılabilir?

IoC, birim testini izolasyonda (örn. Taklit kullanarak) kolaylaştıracak programlama paradigmalarını uygulayacaktır: arayüz kullanımı, yeni () yok, tekil yok ...

Ancak test için IoC konteynerini kullanmak gerçekten bir gereklilik değildir, sadece bazı kolaylıklar sağlayacaktır, örneğin taklit enjeksiyonu ancak bunu manuel olarak yapabilirsiniz.

IoC kullanarak büyük bir çözümde (50'den fazla proje) taklitleri yönetmek faydalı mı?

IoC kullanarak taklitleri yönetmekle ne demek istediğinizden emin değilim. Her neyse, IoC konteynerleri, test söz konusu olduğunda genellikle taklit yapmaktan daha fazlasını yapabilir. Ve yeniden düzenlemeyi mümkün kılan iyi bir IDE desteğiniz varsa, neden kullanmıyorsunuz?

Herhangi bir deneyim?

Evet, büyük bir çözümde, her zamankinden daha fazla hata eğilimli olmayan ve yeniden düzenleme-olumsuz bir çözüme ihtiyacınız var (yani, güvenli bir IoC konteyneri veya iyi bir IDE desteği aracılığıyla).


17

Testlerimde sıklıkla bir IoC konteyneri kullanıyorum. Kabul edelim ki, bunlar saf anlamda "birim testleri" değildir. IMO Bunlar daha BDDish'tir ve yeniden düzenlemeyi kolaylaştırır. Yeniden düzenleme konusunda size güven vermek için testler vardır. Kötü yazılmış testler, kodunuza çimento dökmek gibi olabilir.

Aşağıdakileri göz önünde bulundur:

[TestFixture]
public class ImageGalleryFixture : ContainerWiredFixture
{
    [Test]
    public void Should_save_image()
    {
        container.ConfigureMockFor<IFileRepository>()
            .Setup(r => r.Create(It.IsAny<IFile>()))
            .Verifiable();

        AddToGallery(new RequestWithRealFile());

        container.VerifyMockFor<IFileRepository>();
    }

    private void AddToGallery(AddBusinessImage request)
    {
        container.Resolve<BusinessPublisher>().Consume(request);
    }
}

Galeriye bir resim eklerken gerçekleşen birkaç şey var. Görüntü yeniden boyutlandırılır, bir küçük resim oluşturulur ve dosyalar AmazonS3'te depolanır. Bir konteyner kullanarak, sadece test etmek istediğim davranışı daha kolay bir şekilde izole edebilirim, bu durumda bu kalıcı kısımdır.

Bu tekniği kullanırken bir otomatik alaycı kapsayıcı uzantısı kullanışlıdır: http://www.agileatwork.com/auto-mocking-unity-container-extension/


8
"Kodunuza çimento dökmek gibi" ifadesi için +1. Her zaman kullanmaya başladım.
Andrew Shepherd

2

SimpleInjector , DryIoc (benimki) gibi kayıtsız / bilinmeyen hizmetleri çözme becerisine sahip kapsayıcıların kullanılması , henüz uygulanmamış arabirimler için taklitler döndürebilir.

Bu, geliştirmeye ilk basit uygulama ve alay konusu bağımlılıkları ile başlayabileceğiniz ve ilerledikçe bunları gerçek şeylerle değiştirebileceğiniz anlamına gelir.

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.