2012-06-05 8 views
16

Normalerweise testen Sie, wenn eine Ausnahme in einer bestimmten Methode ausgelöst wird, wie folgt. Ich benutze FluentAssertions:Gibt es eine geeignetere zu testen, wenn der Konstruktor eine Ausnahme auslöst?

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

Aber wie kann man testen, ob eine Ausnahme im Konstruktor geworfen wird? Ich habe es gerade so gemacht, aber gibt es vielleicht einen geeigneteren Weg über FluentAssertions?

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

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

Ich weiß nicht, die Bibliothek, aber Ich mag, was Sie getan haben –

Antwort

13

das genau ist, wie Sie für Ausnahmen testen soll und das ist, was ShouldThrow<T>() und ShouldNotThrow<T>() für in erster Linie entworfen wurden. Tatsächlich könnte der Ansatz Invoking() in der nächsten großen Version (2.0.0) als veraltet markiert werden.

+0

Aber ist es der richtige Weg ist, zu prüfen, ob eine Exception wird im Konstruktor geworfen? Über diese Aktion? –

+1

Schade, dass Sie die Methode Invoking() veraltet haben. Ich finde es viel einfacher zu lesen als der Aktionsmechanismus, der im zweiten Test oben angezeigt wird. Aufrufen hält alles schön zusammen, so dass die Absicht offensichtlich ist. –

+0

@ebeen Normalerweise verwende ich nur die [ExpectedException (typeof (ArgumentNullException))] beim Testen von Exceptions, die vom Konstruktor geworfen werden. Da im Test nur eine Zeile vorhanden ist, kann die Ausnahme nur von dort ausgelöst werden. –

0

Ich habe eine Hilfsmethode, wie die unten für die Verwendung beim Testen Bauer:

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

die ich dann wie folgt verwenden:

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

Ich weiß, es ist eine Frage des persönlichen Geschmacks, aber ich finde das ein bisschen sauberer, als erst einen Delegaten deklarieren und zuweisen zu müssen.

Dies würde den Code in der ursprünglichen Frage wie folgt aussehen:

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