2009-09-23 21 views
92

Jak używać kontenera IoC do testowania urządzenia? Czy przydatne jest zarządzanie makietami w ogromnym rozwiązaniu (ponad 50 projektów) przy użyciu IoC? Jakieś doświadczenia? Jakieś biblioteki C#, które działają dobrze, aby używać go w testach jednostkowych?Używanie IoC do testowania jednostek

+7

@ Mark Seemann byłby zbyt skromny, by to wskazać, ale jeśli jesteś zainteresowany tym pytaniem, powinieneś przynajmniej znać [AutoFixture] (http://autofixture.codeplex.com) –

+0

Jest dobry mówić o związku między DI i kpiąc z Vimeo przez Miguel Castro: https://vimeo.com/68390510 – GregC

Odpowiedz

118

Ogólnie rzecz biorąc, pojemnik DI nie powinien być konieczny do testowania urządzenia, ponieważ testowanie jednostkowe polega na oddzieleniu odpowiedzialności.

Rozważmy klasę, która używa konstruktora iniekcji

public MyClass(IMyDependency dep) { } 

W całej aplikacji, może się okazać, że istnieje ogromna zależność wykres ukryte za IMyDependency, ale w badanej jednostki, należy spłaszczyć to wszystko na jedno Test Double.

Można użyć dynamicznych makiet takich jak Moq lub RhinoMocks, aby wygenerować podwójny test, ale nie jest to wymagane.

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

W niektórych przypadkach auto-mocking container może być miło mieć, ale nie trzeba korzystać z tego samego kontenera DI że stosowanie produkcji użyto.

+12

zgodził ... chyba że cel testowy ma kontener IoC * jako * zależność, twoje testy nie powinny ich potrzebować .. - usuniesz większość wykresu obiektów podczas przeprowadzania testów jednostkowych. –

+3

@ Mark Seemann To ma sens ... Ale co z testami integracyjnymi? Np. Bawiłem się testami interfejsu i musiałem zmierzyć się z sytuacją, kiedy musiałem dzielić się składem pierwiastków. Wszelkie komentarze? –

+3

@ Arnis L .: W przypadku testów integracyjnych jest to mniej ważne. Możesz użyć pojemnika DI do podłączenia komponentów, ale jeśli tak, prawdopodobnie będziesz potrzebował innej konfiguracji pojemnika niż w pełnej aplikacji - chyba że wykonasz test podskórny lub pełny test systemu, w którym to przypadku możesz ponownie użyć konfiguracji aplikacji Kontenera. –

15

Jak używać kontenera Ioc do testowania urządzenia?

IoC wymusi paradygmat programowania, które uczynią testów jednostkowych w izolacji (tj używając mocks) prościej wykorzystanie interfejsów, żadne nowe(), nie singletons ...

ale przy użyciu kontenera IoC do testowania tak naprawdę nie jest wymogiem, po prostu zapewni pewne udogodnienia, np wstrzyknięcie mocków, ale możesz zrobić to ręcznie.

Czy można używać mopów w ogromnym rozwiązaniu (50+ projektów) przy użyciu IoC?

Nie jestem pewien, co rozumiesz przez zarządzanie mockami przy użyciu IoC. W każdym razie, pojemniki IoC mogą zwykle zrobić coś więcej niż tylko wstrzykiwanie mocków, jeśli chodzi o testowanie. A jeśli masz przyzwoitą obsługę IDE, która umożliwia refaktoryzację, dlaczego jej nie używać?

Jakieś doświadczenie?

Tak, w przypadku ogromnego rozwiązania, bardziej niż kiedykolwiek potrzebne jest rozwiązanie niewrażliwe na błędy i zapobiegające refaktoryzacji (np. Za pomocą bezpiecznego kontenera IoC lub dobrej obsługi IDE).

13

Często używam kontenera IoC w moich testach. Oczywiście, nie są to "testy jednostkowe" w czystym tego słowa znaczeniu. IMO Są bardziej BDDish i ułatwiają refaktoryzację. Testy są po to, aby dać ci pewność, że to refaktor. Źle napisane testy mogą być jak wlewanie cementu do twojego kodu.

Rozważmy następujący:

[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); 
    } 
} 

Jest kilka rzeczy, które zdarzają się podczas dodawania zdjęcia do galerii. Rozmiar obrazu zostanie zmieniony, wygenerowana zostanie miniatura, a pliki zostaną zapisane na AmazonS3. Korzystając z pojemnika mogę łatwiej izolować zachowanie, które chcę przetestować, co w tym przypadku jest częścią trwającą.

Automatyczne-szyderczy rozszerzenie zbiornik jest przydatna przy korzystaniu z tej techniki: http://www.agileatwork.com/auto-mocking-unity-container-extension/

+7

+1 dla frazy "jak wylewanie cementuj w swoim kodzie ". Zacząłem go używać cały czas. –

2

Korzystanie z pojemników z możliwością rozwiązania niezarejestrowanych/usługi niezalogowany jak SimpleInjector, DryIoc (jego mine) może powrócić mocks dla dotychczas realizowanych interfejsów .

Oznacza to, że można rozpocząć projektowanie od pierwszej prostej implementacji i wyśmiewanych zależności, a zastępując je rzeczywistymi postępami.

Powiązane problemy