2012-06-13 14 views
13

Sto usando xUnit, SubSpec e FakeItEasy per i miei test di unità. Ho finora creato alcuni test di unità positivi come il seguente:Come verificare le eccezioni generate usando xUnit, SubSpec e 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)); 

Ma ora voglio scrivere alcuni test di unità negativi e verificare che certi metodi non vengono chiamati, e viene generata un'eccezione

es.

"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 
    ); 

posso vedere FakeItEasy ha un metodo di estensione MustNotHaveHappened e xUnit ha un metodo Assert.Throws.

Ma come faccio a mettere tutto insieme?

L'eccezione che voglio testare deve verificarsi quando viene chiamato il metodo Save. Quindi suppongo che dovrei avvolgere un metodo Assert.Throws attorno alla chiamata del metodo presenter.Save(), ma pensavo che il metodo presenter.Save venisse chiamato nel .Do (() => ...

si può si prega di avvisare se il mio test di unità dovrebbe essere simile al di sotto o qualcos'altro?

"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()); 

Molte grazie

+0

Non sono sicuro che questo potrebbe aiutare, ma Hai controllato la documentazione sul SubSpec per esempio https://bitbucket.org/johannesrudolph/subspec/src/a35fcc8ae1f6/test/SubSpec.Tests/ContextSetupTeardownBehavior.cs anche questi sono Test basati su BDD/Specifiche non Test unitari. Potresti ottenere un pubblico migliore se includi il tag BDD. – Spock

risposta

6

lo farei in questo modo:

"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() 
    ); 

O meglio ancora, il passaggio SubSpec per xBehave.net e l'introduzione di 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

io non ho sentito di fakeItEasy o subSpec (sei prove di guardare piuttosto funky, quindi potrei controllare questi fuori :)). Comunque, io faccio uso xUnit quindi questo potrebbe essere utile:

Io uso Record.Exception con Assert.ThrowsDelegate

Quindi qualcosa di simile:

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

Speranza che aiuta.

2

Questo è un modo per farlo in FakeItEasy.

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

Ricevo un "Azione non contiene una definizione per ShouldThrow ..." Quale riferimento/assembly devo includere? – unekwu

Problemi correlati