2012-06-13 33 views
13

Estoy usando xUnit, SubSpec y FakeItEasy para las pruebas de mi unidad. que he creado hasta ahora algunas pruebas unitarias positivas como las siguientes:Cómo probar las excepciones lanzadas con xUnit, SubSpec y 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)); 

Pero ahora quiero escribir algunas pruebas unitarios negativos y comprobar que ciertos métodos no se les llama, y ​​se produce una excepción

por ej.

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

puedo ver FakeItEasy tiene un método de extensión MustNotHaveHappened, y xUnit tiene un método Assert.Throws.

¿Pero cómo lo pongo todo junto?

La excepción que quiero probar debe producirse cuando se llama al método Guardar. Así que supongo que debería envolver un método de Assert.Throws alrededor del presentador. Llamada al método Save(), pero pensé que el método presentador.Save debería llamarse en .Do (() => ...

¿puede usted por favor avise si mi prueba de la unidad debe ser similar por debajo o por alguna otra cosa?

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

Muchas gracias

+0

No estoy seguro de que esto podría ayudar, pero no se compruebe la documentación sobre SubSpec por ejemplo https://bitbucket.org/johannesrudolph/subspec/src/a35fcc8ae1f6/test/SubSpec.Tests/ContextSetupTeardownBehavior.cs también estos son Pruebas basadas en BDD/Especificación no Pruebas unitarias. Es posible que tenga una mejor audiencia si incluye la etiqueta BDD. – Spock

Respuesta

6

lo haría así:

"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 mejor aún, el cambio SubSpec para xBehave.net e introduciendo 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

yo no he escuchado de fakeItEasy o subSpec (eres pruebas parecen bastante cobarde, por lo que podría mira esto :)). Sin embargo, yo utilizo xUnit así que esto puede ser útil:

utilizo Record.Exception con Assert.ThrowsDelegate

Así que algo como:

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

Espero que ayude.

2

Esta es una manera de hacerlo en FakeItEasy.

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

Obtengo una "Acción no contiene una definición para ShouldThrow ..." ¿Qué referencia/ensamblaje necesito incluir? – unekwu

Cuestiones relacionadas