Wie verwende ich
Assert
(oder eine andere Testklasse?), Um zu überprüfen, ob eine Ausnahme ausgelöst wurde?
830
Wie verwende ich
Assert
(oder eine andere Testklasse?), Um zu überprüfen, ob eine Ausnahme ausgelöst wurde?
Antworten:
Für "Visual Studio Team Test" wenden Sie anscheinend das ExpectedException-Attribut auf die Testmethode an.
Beispiel aus der Dokumentation hier: Eine exemplarische Vorgehensweise zum Testen von Einheiten mit Visual Studio Team Test
quelle
Normalerweise hat Ihr Test-Framework eine Antwort darauf. Aber wenn es nicht flexibel genug ist, können Sie dies immer tun:
Wie @Jonas hervorhebt, funktioniert dies NICHT, um eine Basis zu fangen. Ausnahme:
Wenn Sie Exception unbedingt abfangen müssen, müssen Sie Assert.Fail () erneut auslösen. Aber wirklich, das ist ein Zeichen, dass Sie dies nicht von Hand schreiben sollten. Überprüfen Sie Ihr Testframework auf Optionen oder prüfen Sie, ob Sie eine aussagekräftigere Ausnahme zum Testen auslösen können.
Sie sollten in der Lage sein, diesen Ansatz an Ihre Bedürfnisse anzupassen - einschließlich der Angabe, welche Arten von Ausnahmen zu fangen sind. Wenn Sie nur bestimmte Typen erwarten, beenden Sie die
catch
Blöcke mit:quelle
Meine bevorzugte Methode, um dies zu implementieren, besteht darin, eine Methode namens Throws zu schreiben und sie wie jede andere Assert-Methode zu verwenden. Leider können Sie in .NET keine statische Erweiterungsmethode schreiben, sodass Sie diese Methode nicht so verwenden können, als ob sie tatsächlich zur Build-in-Assert-Klasse gehört. mach einfach einen anderen namens MyAssert oder ähnliches. Die Klasse sieht so aus:
Das bedeutet, dass Ihr Komponententest folgendermaßen aussieht:
Das sieht und verhält sich viel mehr wie der Rest Ihrer Unit-Test-Syntax.
quelle
Assert.ThrowsException<T>
undAssert.ThrowsExceptionAsync<T>
- siehe blogs.msdn.microsoft.com/visualstudioalm/2017/02/25/…Wenn Sie NUNIT verwenden, können Sie Folgendes tun:
Es ist auch möglich, die ausgelöste Ausnahme zu speichern, um sie weiter zu validieren:
Siehe: http://nunit.org/docs/2.5/exceptionAsserts.html
quelle
Wenn Sie MSTest verwenden, das ursprünglich kein
ExpectedException
Attribut hatte, können Sie Folgendes tun:quelle
Seien Sie vorsichtig bei der Verwendung von ExpectedException, da dies zu mehreren Fallstricken führen kann, wie hier gezeigt:
http://geekswithblogs.net/sdorman/archive/2009/01/17/unit-testing-and-expected-exceptions.aspx
Und hier:
http://xunit.github.io/docs/comparisons.html
Wenn Sie auf Ausnahmen testen müssen, gibt es weniger verpönte Möglichkeiten. Sie können die Methode try {act / fail} catch {assert} verwenden, die für Frameworks hilfreich sein kann, die andere Ausnahmetests als ExpectedException nicht direkt unterstützen.
Eine bessere Alternative ist die Verwendung von xUnit.NET, einem sehr modernen, zukunftsorientierten und erweiterbaren Unit-Test-Framework, das aus allen anderen Fehlern gelernt und verbessert hat. Eine solche Verbesserung ist Assert.Throws, die eine viel bessere Syntax zum Aktivieren von Ausnahmen bietet.
Sie finden xUnit.NET unter github: http://xunit.github.io/
quelle
MSTest (v2) verfügt jetzt über eine Assert.ThrowsException-Funktion, die wie folgt verwendet werden kann:
Sie können es mit nuget installieren:
Install-Package MSTest.TestFramework
quelle
In einem Projekt, an dem ich arbeite, haben wir eine andere Lösung dafür.
Zuerst mag ich das ExpectedExceptionAttribute nicht, weil es berücksichtigt, welcher Methodenaufruf die Exception verursacht hat.
Ich mache das stattdessen mit einer Hilfsmethode.
Prüfung
HelperMethod
Ordentlich, nicht wahr?
quelle
Es ist ein Attribut für die Testmethode ... Sie verwenden Assert nicht. Sieht aus wie das:
quelle
Sie können ein Paket von Nuget herunterladen, indem Sie: PM> Install-Package MSTestExtensions verwenden , das Assert.Throws () hinzufügt. Syntax im Stil von nUnit / xUnit hinzuzufügen.
Allgemeine Anweisungen: Laden Sie die Assembly herunter und erben Sie sie von BaseTest. Sie können dann Assert.Throws () verwenden. Syntax .
Die Hauptmethode für die Throws-Implementierung sieht wie folgt aus:
Offenlegung: Ich habe dieses Paket zusammengestellt.
Weitere Informationen: http://www.bradoncode.com/blog/2012/01/asserting-exceptions-in-mstest-with.html
quelle
Sie können dies mit einer einfachen einzeiligen erreichen.
Wenn Ihre Operation
foo.bar()
asynchron ist:Wenn
foo.bar()
ist nicht asynchronquelle
ArgumentException
. Der alte Versuch, die Ausnahmeantwort abzufangen und zu testen, wird immer noch bevorzugt, wenn Sie erweiterte Kriterien zum Testen haben, aber in vielen meiner Fälle hilft dies sehr!Ich empfehle nicht, das ExpectedException-Attribut zu verwenden (da es zu einschränkend und fehleranfällig ist) oder in jedem Test einen Try / Catch-Block zu schreiben (da es zu kompliziert und fehleranfällig ist). Verwenden Sie eine gut konzipierte Assert-Methode - entweder von Ihrem Test-Framework bereitgestellt oder schreiben Sie Ihre eigene. Folgendes habe ich geschrieben und verwendet.
Beispiel verwendet:
ANMERKUNGEN
Das Zurückgeben der Ausnahme anstelle der Unterstützung eines Validierungsrückrufs ist eine vernünftige Idee, mit der Ausnahme, dass sich dadurch die aufrufende Syntax dieser Behauptung stark von anderen von mir verwendeten Behauptungen unterscheidet.
Im Gegensatz zu anderen verwende ich "Propagates" anstelle von "Throws", da wir nur testen können, ob sich eine Ausnahme von einem Aufruf ausbreitet. Wir können nicht direkt testen, ob eine Ausnahme ausgelöst wird. Aber ich nehme an, Sie könnten sich Würfe vorstellen, die bedeuten: geworfen und nicht gefangen.
LETZTER GEDANKE
Bevor ich zu diesem Ansatz wechselte, habe ich erwogen, das Attribut ExpectedException zu verwenden, wenn ein Test nur den Ausnahmetyp verifizierte, und einen Try / Catch-Block zu verwenden, wenn weitere Validierungen erforderlich waren. Aber ich musste nicht nur darüber nachdenken, welche Technik für jeden Test verwendet werden sollte, sondern es war auch kein trivialer Aufwand, den Code von einer Technik zur anderen zu ändern, wenn sich die Anforderungen änderten. Die Verwendung eines einheitlichen Ansatzes spart geistige Anstrengung.
Zusammenfassend ist dieser Ansatz sportlich: Benutzerfreundlichkeit, Flexibilität und Robustheit (schwer falsch zu machen).
quelle
Der von @Richiban oben bereitgestellte Helfer funktioniert hervorragend, außer er behandelt nicht die Situation, in der eine Ausnahme ausgelöst wird, aber nicht den erwarteten Typ. Die folgenden Adressen, die:
quelle
Da Sie die Verwendung anderer Testklassen erwähnen ,
ExpectedException
ist die Verwendung von Shoudlys Should.Throw eine bessere Option als das Attribut .Angenommen, der Kunde muss eine Adresse haben , um eine Bestellung zu erstellen . Wenn nicht, sollte die
CreateOrderForCustomer
Methode zu einem führenArgumentException
. Dann könnten wir schreiben:Dies ist besser als die Verwendung eines
ExpectedException
Attributs, da wir genau festlegen, was den Fehler auslösen soll. Dies macht die Anforderungen in unseren Tests klarer und erleichtert auch die Diagnose, wenn der Test fehlschlägt.Beachten Sie, dass es auch einen
Should.ThrowAsync
asynchronen Methodentest gibt.quelle
Alternativ können Sie versuchen, Ausnahmen zu testen, die tatsächlich mit den nächsten 2 Zeilen in Ihrem Test ausgelöst werden.
quelle
Wenn Sie beim integrierten VS-Komponententest lediglich überprüfen möchten, ob "eine Ausnahme" ausgelöst wird, den Typ jedoch nicht kennen, können Sie einen catch all verwenden:
quelle
Nun, ich fasse ziemlich genau zusammen, was alle anderen hier zuvor gesagt haben ... Wie auch immer, hier ist der Code, den ich gemäß den guten Antworten erstellt habe :) Alles, was zu tun bleibt, ist zu kopieren und zu verwenden ...
quelle
In den nUnit-Dokumenten finden Sie Beispiele zu folgenden Themen :
quelle
Dies hängt davon ab, welches Testframework Sie verwenden.
In MbUnit können Sie beispielsweise die erwartete Ausnahme mit einem Attribut angeben, um sicherzustellen, dass Sie die Ausnahme erhalten, die Sie wirklich erwarten.
quelle
Versuchen Sie bei Verwendung von NUnit Folgendes :
quelle
Es gibt eine großartige Bibliothek namens NFluent , die das Schreiben Ihrer Behauptungen beschleunigt und vereinfacht .
Es ist ziemlich einfach, eine Behauptung zu schreiben, um eine Ausnahme auszulösen:
quelle
Auch wenn dies eine alte Frage ist, möchte ich der Diskussion einen neuen Gedanken hinzufügen. Ich habe das zu erwartende Muster "Anordnen, Handeln, Bestätigen", "Anordnen, Handeln, Bestätigen" erweitert. Sie können einen erwarteten Ausnahmezeiger erstellen und dann bestätigen, dass er zugewiesen wurde. Dies fühlt sich sauberer an, als Ihre Asserts in einem Catch-Block auszuführen, sodass Ihr Act-Abschnitt meist nur für die eine Codezeile übrig bleibt, um die zu testende Methode aufzurufen. Sie müssen auch nicht zu
Assert.Fail();
oderreturn
von mehreren Punkten im Code. Jede andere ausgelöste Ausnahme führt dazu, dass der Test fehlschlägt, da er nicht abgefangen wird. Wenn eine Ausnahme Ihres erwarteten Typs ausgelöst wird, diese jedoch nicht die erwartete war, wird dies gegen die Nachricht oder andere Eigenschaften von bestätigt Mit der Ausnahme stellen Sie sicher, dass Ihr Test nicht versehentlich bestanden wird.quelle