Verwenden Sie die NUnit Assert.Throws-Methode oder das ExpectedException-Attribut?

146

Ich habe festgestellt, dass dies die beiden Hauptmethoden zum Testen auf Ausnahmen zu sein scheinen:

Assert.Throws<Exception>(()=>MethodThatThrows());

[ExpectedException(typeof(Exception))]

Welches davon wäre das Beste? Bietet einer Vorteile gegenüber dem anderen? Oder ist es einfach eine Frage der persönlichen Präferenz?

SamuelDavis
quelle
3
Eine dritte Option ist der fließende Stil:Assert.That(() => MethodThatThrows(), Throws.Exception)
Jack Ukleja
1
NUnit Version 3 und höher unterstützt das ExpectedExceptionAttribut nicht mehr , sodass für Version 3+ nur die Assert.ThrowsVariante relevant ist.
Joanlofe
Wieso ist es so? Dass Nunit3 beschlossen hat, diese Unterstützung einzustellen? Googelte herum und konnte keine Erklärung dafür finden ... JUnit unterstützt diesen Weg immer noch, nicht wahr?
Ahaaman

Antworten:

91

Mit dem ersten können Sie mit mehreren Aufrufen auf mehr als eine Ausnahme testen:

Assert.Throws(()=>MethodThatThrows());
Assert.Throws(()=>Method2ThatThrows());

Mit der zweiten können Sie nur eine Ausnahme pro Testfunktion testen.

chue x
quelle
25
Ein Test sollte nur ein bestimmtes Stück Logik testen. Würde das Testen von zwei Fehlern im selben Komponententest nicht als schlechte Praxis angesehen?
Samuel Davis
5
@SamuelDavis - Im Allgemeinen möchten Sie nicht verschiedene Fälle im selben Test testen. Es kann jedoch einen Anwendungsfall für mehrere geben Assert.Throws.
Chue x
3
In beiden Fällen erhalten Sie hier die Ausnahme als Parameter, mit dem Sie Details in der Ausnahme bestätigen können. Die Verwendung von "Erwartete Ausnahme" schützt Sie auch nicht vor demselben Ausnahmetyp, der in einem anderen Methodenaufruf ausgelöst wird. Hier zielen Sie auf die genaue Methode und nicht auf den gesamten Test. Obwohl Ihr Test nur sehr wenig Code enthalten sollte, sind Sie nie zu sicher. Besonders wenn Code komplex und / oder Ausnahme zu allgemein wird. Dinge wie "ArgumentNullExceptions" können häufig ausgelöst werden und werden beispielsweise mit der ExpectedException leicht übersehen. Assert.Throws würde es nicht verpassen.
Gil Sand
254

Der Hauptunterschied ist:

ExpectedException()Das Attribut lässt den Test bestehen, wenn an einer beliebigen Stelle in der Testmethode eine Ausnahme auftritt .
Durch die Verwendung von Assert.Throws()können Sie den exactOrt des Codes angeben , an dem eine Ausnahme erwartet wird.

NUnit 3.0 lässt die offizielle Unterstützung für ExpectedExceptioninsgesamt fallen.

Daher bevorzuge ich definitiv die Verwendung einer Assert.Throws()Methode anstelle eines ExpectedException()Attributs.

Alexander Stepaniuk
quelle
7
Dies ist bei weitem die richtige Antwort. Im Übrigen gibt Assert.Throws () auch die Ausnahme zurück, die eine zusätzliche Überprüfung der Eigenschaften der Ausnahme ermöglichen kann, wenn sie für Sie von Bedeutung sind.
Perfektionist
1
Beantworten Sie schließlich, warum ich ExpectedException nicht zum
Laufen bringen
2
Hier ist der Link github.com/nunit/docs/wiki/Breaking-Changes - ExpectedExceptionAttribute wird nicht mehr unterstützt.
Anton Lyhin
Um dies so zu ändern, dass es unter NUnit 3.0 funktioniert, ändern Sie es wie folgt
Andrei Krasutski
38

Ich bevorzuge assert.throws, da ich damit andere Bedingungen überprüfen und bestätigen kann, nachdem die Ausnahme ausgelöst wurde.

    [Test]
    [Category("Slow")]
    public void IsValidLogFileName_nullFileName_ThrowsExcpetion()
    {
        // the exception we expect thrown from the IsValidFileName method
        var ex = Assert.Throws<ArgumentNullException>(() => a.IsValidLogFileName(""));

        // now we can test the exception itself
        Assert.That(ex.Message == "Blah");

    }
Mike Parkhill
quelle
Dies ist eine der besseren Antworten. Es ist ziemlich häufig, dass Sie überprüfen möchten, ob etwas in einen fehlerhaften Zustand eingetreten ist, nachdem die Ausnahme ausgelöst wurde.
Rhys Bevilaqua
10

Sie können den erwarteten Fehler auch stark eingeben (wie die alte Attributversion).

Assert.Throws<System.InvalidOperationException>(() => breakingAction())
Reverend Sfinks
quelle