2012-06-13 13 views
13

Używam xUnit, SubSpec i FakeItEasy do moich testów jednostkowych. mam tak daleko stworzył pewne pozytywne testy jednostkowe tak:Jak testować wyjątki wyrzucane przy użyciu xUnit, SubSpec i FakeItEasy

"Given a Options presenter" 
    .Context(() => 
     presenter = new OptionsPresenter(view, 
             A<IOptionsModel>.Ignored, 
             service)); 

"with the Initialize method called to retrieve the option values" 
    .Do(() => 
     presenter.Initialize()); 

"expect the view not to be null" 
    .Observation(() => 
     Assert.NotNull(view)); 

"expect the view AutoSave property to be true" 
    .Observation(() => Assert.True(view.AutoSave)); 

Ale teraz chcę napisać kilka negatywnych testów jednostkowych i sprawdzić, że niektóre metody nie sprawdzony i jest wyjątek

np.

"Given a Options presenter" 
    .Context(() => 
     presenter = new OptionsPresenter(view, 
             A<IOptionsModel>.Ignored, 
             service)); 

"with the Save method called to save the option values" 
    .Do(() => 
     presenter.Save()); 

"expect an ValidationException to be thrown" 
    .Observation(() => 
     // TODO 
    ); 

"expect an service.SaveOptions method not to be called" 
    .Observation(() => 
     // TODO 
    ); 

widzę FakeItEasy ma metodę rozszerzenia MustNotHaveHappened i xUnit ma metodę Assert.Throws.

Ale jak mogę to wszystko połączyć?

Wyjątek, który chcę przetestować, powinien wystąpić po wywołaniu metody Save. Zgaduję więc, że powinienem owinąć metodę Assert.Throws wokół wywołania metody presenter.Save(), ale myślałem, że metoda presenter.Save powinna zostać wywołana w .Do (() => ...

może pan doradzić jeśli testy jednostkowe powinny wyglądać jak poniżej lub coś innego?

"Given a Options presenter" 
    .Context(() =>  
     presenter = new OptionsPresenter(view, 
             model, 
             service)); 

"expect the Presenter.Save call to throw an Exception" 
    .Observation(() => 
     Assert.Throws<FluentValidation.ValidationException>(() => presenter.Save())); 

"expect the Service.SaveOptions method not to be called" 
    .Observation(() => 
     A.CallTo(() => service.SaveOptions(A<IOptionsModel>.Ignored)).MustNotHaveHappened()); 

Dziękujemy

+0

Nie wiesz, że to może pomóc, ale sprawdzić dokumentację SubSpec na przykład https://bitbucket.org/johannesrudolph/subspec/src/a35fcc8ae1f6/test/SubSpec.Tests/ContextSetupTeardownBehavior.cs także są BDD/testy oparte na specyfikacji, a nie testy jednostkowe. Możesz uzyskać lepszą widownię, jeśli umieścisz tag BDD. – Spock

Odpowiedz

6

zrobiłbym to tak:

"Given a Options presenter" 
    .Context(() => 
     presenter = new OptionsPresenter(view, 
             (IOptionsModel)null, 
             service)); 

"with the Save method called to save the option values" 
    .Do(() => 
     exception = Record.Exception(() => presenter.Save())); 

"expect an ValidationException to be thrown" 
    .Observation(() => 
     Assert.IsType<ValidationException>(exception) 
    ); 

"expect an service.SaveOptions method not to be called" 
    .Observation(() => 
     A.CallTo(() => service.SaveOptions(A<IOptionsModel>.Ignored)).MustNotHaveHappened() 
    ); 

albo jeszcze lepiej, przełączanie SubSpec dla xBehave.net i wprowadzenie FluentAssertions: -

"Given an options presenter" 
    .x(() => presenter = new OptionsPresenter(view, (IOptionsModel)null, service)); 

"When saving the options presenter" 
    .x(() => exception = Record.Exception(() => presenter.Save())); 

"Then a validation exception is thrown" 
    .x(() => exception.Should().BeOfType<ValiationException>()); 

"And the options model must not be saved" 
    .x(() => A.CallTo(() => 
     service.SaveOptions(A<IOptionsModel>.Ignored)).MustNotHaveHappened()); 
10

ja nie słyszałem o fakeItEasy lub subSpec (jesteś testy wyglądają całkiem funky, więc może sprawdź to :)). Jednak ja używam xUnit więc może to być pomocne:

używam Record.Exception z Assert.ThrowsDelegate

Więc coś takiego:

[Fact] 
    public void Test() 
    { 
     // Arange 

     // Act 
     Exception ex = Record.Exception(new Assert.ThrowsDelegate(() => { service.DoStuff(); })); 

     // Assert 
     Assert.IsType(typeof(<whatever exception type you are looking for>), ex); 
     Assert.Equal("<whatever message text you are looking for>", ex.Message); 
    } 

nadzieję, że pomaga.

2

Jest to jeden ze sposobów, aby to zrobić w FakeItEasy.

Action act =() => someObject.SomeMethod(someArgument); 
act.ShouldThrow<Exception>(); 
+0

Otrzymuję "Akcja nie zawiera definicji dla ShouldThrow ..." Jakie odniesienie/zestaw muszę dołączyć? – unekwu

Powiązane problemy