2012-06-05 23 views
16

Normalmente prueba, si se lanza una excepción en un método determinado, de la siguiente manera. utilizo FluentAssertions:¿Hay alguna más apropiada para probar si el constructor arroja una excepción?

[Fact] 
public void Exception_gets_thrown() 
{ 
    // Arrange 
    var foo = new Foo("validArgument"); 

    // Act/Assert 
    foo.Invoking(f => f.Bar(null))   // null is an invalid argument 
     .ShouldThrow<ArgumentNullException>(); 
} 

Pero cómo probar, si una excepción es lanzada en el constructor? Lo acabo de hacer así, pero ¿hay quizás una forma más apropiada de a través de FluentAssertions?

[Fact] 
public void Constructor_throws_Exception() 
{ 
    // Arrange 
    Action a =() => new Foo(null);   // null is an invalid argument 

    // Act/Assert 
    a.ShouldThrow<ArgumentNullException>(); 
} 
+2

No sé la biblioteca, pero me gusta lo que has hecho –

Respuesta

13

eso es exactamente lo que se supone que la prueba de excepciones y eso es lo ShouldThrow<T>() y ShouldNotThrow<T>() fue diseñada para en el primer lugar. De hecho, el enfoque Invoking() podría marcarse como obsoleto en la próxima versión grande (2.0.0).

+0

Pero, ¿es la forma correcta de la prueba, si una excepción se arroja en el constructor? A través de esta acción? –

+1

Es una pena que el enfoque Invoking() quede obsoleto. Me resulta mucho más fácil de leer que el mecanismo de acción que se muestra en la segunda prueba anterior. Invocar mantiene todo muy bien junto así que la intención es obvia. –

+0

@ebeen Normalmente utilizo [ExpectedException (typeof (ArgumentNullException))] al probar las excepciones lanzadas desde el constructor. Dado que solo hay una línea en la prueba, la excepción solo puede arrojarse desde allí. –

0

he añadido un método de ayuda al igual que los constructores a continuación para su uso cuando la prueba:

static Action Constructor<T>(Func<T> func) 
{ 
    return() => func(); 
} 

que luego utilizo como esto:

Constructor(() => new Foo("bar", null)) 
.ShouldThrow<ArgumentNullException>() 
.And 
.ParamName 
.Should() 
.Be("baz"); 

Sé que es una cuestión de gusto personal, pero encuentra esto un poco más limpio que la necesidad de declarar y asignar un delegado primero.

Esto haría que el código en la pregunta original aspecto:

[Fact] 
public void Constructor_throws_Exception() 
{  
    // Act/Assert 
    Constructor(() => new Foo(null)).ShouldThrow<ArgumentNullException>(); 
} 
Cuestiones relacionadas