Wie verwende ich Assert, 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?

Alex
quelle
Welches Unit-Testing-Framework verwenden Sie?
Kevin Pullin
3
Visual Studio Integrated
Alex
4
Hilft das Attribut ExpectedException nicht? ref: msdn.microsoft.com/en-us/library/…
shahkalpesh
2
Komisch, ich habe gerade nach der Antwort gesucht und sie unter stackoverflow.com/questions/741029/testing-exceptions gefunden .
Dfjacobs

Antworten:

978

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

[TestMethod]
[ExpectedException(typeof(ArgumentException),
    "A userId of null was inappropriately allowed.")]
public void NullUserIdInConstructor()
{
   LogonInfo logonInfo = new LogonInfo(null, "P@ss0word");
}
Kevin Pullin
quelle
25
Das obige ExpectedException-Attribut funktioniert auch in NUnit (aber [TestMethod] sollte [Test] sein).
dbkk
5
@dbkk: Funktioniert in NUnit nicht genau gleich - die Nachricht wird als Zeichenfolge behandelt, die die Ausnahmemeldung matcvh muss (und IU hält das für sinnvoller)
Ruben Bartelink
29
Dieses Attribut erledigt die Aufgabe und ist eine integrierte Funktion für C # -Programmierer. Ich empfehle jedoch nicht, es zu verwenden, da es nicht flexibel genug ist. Überlegen Sie, was passiert, wenn der Ausnahmetyp von Ihrem Test-Setup-Code ausgelöst wird: Der Test besteht, hat aber nicht das getan, was Sie erwartet haben. Oder was ist, wenn Sie den Status des Ausnahmeobjekts testen möchten? Normalerweise möchte ich StringAssert.Contains (e.Message ...) verwenden, anstatt die gesamte Nachricht zu testen. Verwenden Sie eine Assert-Methode, wie in anderen Antworten beschrieben.
Steve
3
Vermeiden Sie die Verwendung von ExpectedException in NUnit, da diese in NUnit 3.0 gelöscht wird. Ich bevorzuge Assert.Throws <SpecificException> ()
Terence
5
Sie können Assert.ThrowsException <T> und Assert.ThrowsExceptionAsync <T> in MsTest verwenden.
Gopal Krishnan
257

Normalerweise hat Ihr Test-Framework eine Antwort darauf. Aber wenn es nicht flexibel genug ist, können Sie dies immer tun:

try {
    somethingThatShouldThrowAnException();
    Assert.Fail(); // If it gets to this line, no exception was thrown
} catch (GoodException) { }

Wie @Jonas hervorhebt, funktioniert dies NICHT, um eine Basis zu fangen. Ausnahme:

try {
    somethingThatShouldThrowAnException();
    Assert.Fail(); // raises AssertionException
} catch (Exception) {
    // Catches the assertion exception, and the test passes
}

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.

catch (AssertionException) { throw; }

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 catchBlöcke mit:

} catch (GoodException) {
} catch (Exception) {
    // not the right kind of exception
    Assert.Fail();
}
ojrac
quelle
20
+1, ich verwende diese Methode anstelle des Attributs, wenn ich Aussagen machen muss, die über die Art der Ausnahme hinausgehen. Was ist beispielsweise, wenn überprüft werden muss, ob bestimmte Felder in der Ausnahmeinstanz auf bestimmte Werte festgelegt sind?
Pavel Repin
2
Sie müssen die Fehlermeldung nicht angeben. Dies ist ausreichend: [ExpectedException (typeof (ArgumentException))]
Mibollma
5
Ich denke, diese Lösung ist die beste. [ExpectedException (typeof (ArgumentException))] hat seine Verwendung, wenn der Test einfach ist, aber meiner Ansicht nach eine träge Lösung ist und es zu Fallstricken führen kann, wenn man sich damit vertraut macht. Diese Lösung gibt Ihnen eine spezifische Kontrolle, um einen korrekteren Test durchzuführen, und Sie können eine Test-Writeline zu Ihrem Testlaufbericht erstellen, dass die Ausnahme tatsächlich wie erwartet ausgelöst wurde.
Evilfish
12
Seien Sie vorsichtig damit, denn Assert.Fail () löst eine Ausnahme aus. Wenn Sie sie abfangen, besteht der Test!
Jonas
4
@ Vinnyq12 Was ich meine ist, dass der erste Test im obigen Beispiel niemals fehlschlagen wird. Ein Test schlägt fehl, wenn eine Ausnahme ausgelöst wird (und nicht vom ExpectedExceptionAttribute "abgefangen" wird)
Jonas
113

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:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace YourProject.Tests
{
    public static class MyAssert
    {
        public static void Throws<T>( Action func ) where T : Exception
        {
            var exceptionThrown = false;
            try
            {
                func.Invoke();
            }
            catch ( T )
            {
                exceptionThrown = true;
            }

            if ( !exceptionThrown )
            {
                throw new AssertFailedException(
                    String.Format("An exception of type {0} was expected, but not thrown", typeof(T))
                    );
            }
        }
    }
}

Das bedeutet, dass Ihr Komponententest folgendermaßen aussieht:

[TestMethod()]
public void ExceptionTest()
{
    String testStr = null;
    MyAssert.Throws<NullReferenceException>(() => testStr.ToUpper());
}

Das sieht und verhält sich viel mehr wie der Rest Ihrer Unit-Test-Syntax.

Richiban
quelle
1
Entfernen Sie das Bool-Flag und setzen Sie den Wurf direkt nach dem Aufruf in die Zeile, um eine kompaktere Implementierung zu erzielen.
gt
11
Das einzige, was dies verbessert, ist, dass die Funktion die abgefangene Ausnahme zurückgibt, damit Sie weiterhin behaupten können, dass Dinge wie die Attribute in der Ausnahme korrekt sind.
Mark Hildreth
2
Vielen Dank! Dies scheint mir der beste Ansatz zu sein, da es eine kurze Möglichkeit ist, mehrere Ausnahmen in einer Methode zu testen. Es ist auch viel besser lesbar.
David Sherret
2
@ MickeyPerlstein-Attribute verstoßen gegen die AAA-Regeln zum Testen. Insbesondere wenn Ihr Arrangement die Ausnahme auslöst, bevor Sie überhaupt zum Gesetz gelangen, besteht Ihr Test ... eek!
Freiheit-m
2
Microsoft hat es endlich geschafft, MSTest zu aktualisieren - v2 unterstützt Assert.ThrowsException<T>und Assert.ThrowsExceptionAsync<T>- siehe blogs.msdn.microsoft.com/visualstudioalm/2017/02/25/…
Quango
62

Wenn Sie NUNIT verwenden, können Sie Folgendes tun:

Assert.Throws<ExpectedException>(() => methodToTest());


Es ist auch möglich, die ausgelöste Ausnahme zu speichern, um sie weiter zu validieren:

ExpectedException ex = Assert.Throws<ExpectedException>(() => methodToTest());
Assert.AreEqual( "Expected message text.", ex.Message );
Assert.AreEqual( 5, ex.SomeNumber);

Siehe: http://nunit.org/docs/2.5/exceptionAsserts.html

Damir
quelle
60

Wenn Sie MSTest verwenden, das ursprünglich kein ExpectedExceptionAttribut hatte, können Sie Folgendes tun:

try 
{
    SomeExceptionThrowingMethod()
    Assert.Fail("no exception thrown");
}
catch (Exception ex)
{
    Assert.IsTrue(ex is SpecificExceptionType);
}
Jon Limjap
quelle
3
Dies funktioniert, aber ich empfehle dies im Allgemeinen nicht, da die Logik zu kompliziert ist. Das heißt nicht, dass es kompliziert ist, aber überlegen Sie, ob Sie diesen Codeblock für mehrere Tests schreiben - 10s, 100s von Tests. Diese Logik muss auf eine gut konzipierte Assert-Methode übertragen werden. Siehe andere Antworten.
Steve
35

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/

jrista
quelle
4
Beachten Sie, dass NUnit 2.5 jetzt auch die Syntax des Assert.Throws-Stils unterstützt - nunit.com/index.php?p=releaseNotes&r=2.5
Alconja
Die Art und Weise, wie die Komponententests aufhören, um Sie über die Ausnahme bei der Verwendung von ExpectedException zu informieren, macht mich verrückt. Warum hielt MS es für eine gute Idee, einen manuellen Schritt in automatisierten Tests durchzuführen? Danke für die Links.
Ameise
@Ant: MS hat NUnit kopiert ... die eigentliche Frage ist also, warum NUnit es für eine gute Idee hielt.
jrista
28

MSTest (v2) verfügt jetzt über eine Assert.ThrowsException-Funktion, die wie folgt verwendet werden kann:

Assert.ThrowsException<System.FormatException>(() =>
            {
                Story actual = PersonalSite.Services.Content.ExtractHeader(String.Empty);
            }); 

Sie können es mit nuget installieren: Install-Package MSTest.TestFramework

Martin Beeby
quelle
Im Jahr 2018 wird dies als bewährte Methode angesehen, da nur das zu testende Gerät und kein anderer Code überprüft wird.
CM
24

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

[TestMethod]
public void AccountRepository_ThrowsExceptionIfFileisCorrupt()
{
     var file = File.Create("Accounts.bin");
     file.WriteByte(1);
     file.Close();

     IAccountRepository repo = new FileAccountRepository();
     TestHelpers.AssertThrows<SerializationException>(()=>repo.GetAll());            
}

HelperMethod

public static TException AssertThrows<TException>(Action action) where TException : Exception
    {
        try
        {
            action();
        }
        catch (TException ex)
        {
            return ex;
        }
        Assert.Fail("Expected exception was not thrown");

        return null;
    }

Ordentlich, nicht wahr?

Glenn
quelle
14

Es ist ein Attribut für die Testmethode ... Sie verwenden Assert nicht. Sieht aus wie das:

[ExpectedException(typeof(ExceptionType))]
public void YourMethod_should_throw_exception()
Bytebender
quelle
13

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:

public static void Throws<T>(Action task, string expectedMessage, ExceptionMessageCompareOptions options) where T : Exception
{
    try
    {
        task();
    }
    catch (Exception ex)
    {
        AssertExceptionType<T>(ex);
        AssertExceptionMessage(ex, expectedMessage, options);
        return;
    }

    if (typeof(T).Equals(new Exception().GetType()))
    {
        Assert.Fail("Expected exception but no exception was thrown.");
    }
    else
    {
        Assert.Fail(string.Format("Expected exception of type {0} but no exception was thrown.", typeof(T)));
    }
}

Offenlegung: Ich habe dieses Paket zusammengestellt.

Weitere Informationen: http://www.bradoncode.com/blog/2012/01/asserting-exceptions-in-mstest-with.html

Bradley Braithwaite
quelle
Danke für das Beispiel. Haben Sie ein Beispiel zum Testen eines Assert.DoesNotThrow () oder eines gleichwertigen?
Lane Goolsby
10

Sie können dies mit einer einfachen einzeiligen erreichen.

Wenn Ihre Operation foo.bar()asynchron ist:

await Assert.ThrowsExceptionAsync<Exception>(() => foo.bar());

Wenn foo.bar()ist nicht asynchron

Assert.ThrowsException<Exception>(() => foo.bar());
Cfrim
quelle
1
Es gibt viele andere Antworten. Für mich suchte ich nach einer Kurzform, um bekannte Fehlerbedingungen nur nach Ausnahmetyp zu testen. Dies führt zu den am einfachsten lesbaren Testfällen. HINWEIS: Der Ausnahmetyp stimmt nicht mit geerbten Ausnahmeklassen wie einem Standard-Try-Catch überein, sodass im obigen Beispiel beispielsweise kein Trap-Typ abgefangen wird 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!
Chris Schaller
5

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.

public static class ExceptionAssert
{
    private static T GetException<T>(Action action, string message="") where T : Exception
    {
        try
        {
            action();
        }
        catch (T exception)
        {
            return exception;
        }
        throw new AssertFailedException("Expected exception " + typeof(T).FullName + ", but none was propagated.  " + message);
    }

    public static void Propagates<T>(Action action) where T : Exception
    {
        Propagates<T>(action, "");
    }

    public static void Propagates<T>(Action action, string message) where T : Exception
    {
        GetException<T>(action, message);
    }

    public static void Propagates<T>(Action action, Action<T> validation) where T : Exception
    {
        Propagates(action, validation, "");
    }

    public static void Propagates<T>(Action action, Action<T> validation, string message) where T : Exception
    {
        validation(GetException<T>(action, message));
    }
}

Beispiel verwendet:

    [TestMethod]
    public void Run_PropagatesWin32Exception_ForInvalidExeFile()
    {
        (test setup that might propagate Win32Exception)
        ExceptionAssert.Propagates<Win32Exception>(
            () => CommandExecutionUtil.Run(Assembly.GetExecutingAssembly().Location, new string[0]));
        (more asserts or something)
    }

    [TestMethod]
    public void Run_PropagatesFileNotFoundException_ForExecutableNotFound()
    {
        (test setup that might propagate FileNotFoundException)
        ExceptionAssert.Propagates<FileNotFoundException>(
            () => CommandExecutionUtil.Run("NotThere.exe", new string[0]),
            e => StringAssert.Contains(e.Message, "NotThere.exe"));
        (more asserts or something)
    }

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).

Steve
quelle
4

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:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace YourProject.Tests
{
    public static class MyAssert
    {
        /// <summary>
        /// Helper for Asserting that a function throws an exception of a particular type.
        /// </summary>
        public static void Throws<T>( Action func ) where T : Exception
        {
            Exception exceptionOther = null;
            var exceptionThrown = false;
            try
            {
                func.Invoke();
            }
            catch ( T )
            {
                exceptionThrown = true;
            }
            catch (Exception e) {
                exceptionOther = e;
            }

            if ( !exceptionThrown )
            {
                if (exceptionOther != null) {
                    throw new AssertFailedException(
                        String.Format("An exception of type {0} was expected, but not thrown. Instead, an exception of type {1} was thrown.", typeof(T), exceptionOther.GetType()),
                        exceptionOther
                        );
                }

                throw new AssertFailedException(
                    String.Format("An exception of type {0} was expected, but no exception was thrown.", typeof(T))
                    );
            }
        }
    }
}
Martin Connell
quelle
2
Hmmm ... Ich verstehe die Idee, bin mir aber nicht sicher, ob es besser ist. Nur weil wir sicherstellen möchten, dass eine bestimmte Ausnahme ausgelöst wird, bedeutet dies nicht, dass alle anderen als Assertionsfehler abgeschlossen werden sollten. IMHO sollte eine unbekannte Ausnahme den Stapel einfach wie bei jeder anderen Assert-Operation in die Luft sprudeln lassen.
Crono
@ Martin Ich würde den Code mit exceptionOther entfernen und einfach aus der zweiten catch-Klausel
Tom Lint
4

Da Sie die Verwendung anderer Testklassen erwähnen , ExpectedExceptionist die Verwendung von Shoudlys Should.Throw eine bessere Option als das Attribut .

Should.Throw<DivideByZeroException>(() => { MyDivideMethod(1, 0); });

Angenommen, der Kunde muss eine Adresse haben , um eine Bestellung zu erstellen . Wenn nicht, sollte die CreateOrderForCustomerMethode zu einem führen ArgumentException. Dann könnten wir schreiben:

[TestMethod]
public void NullUserIdInConstructor()
{
  var customer = new Customer(name := "Justin", address := null};

  Should.Throw<ArgumentException>(() => {
    var order = CreateOrderForCustomer(customer) });
}

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.ThrowAsyncasynchronen Methodentest gibt.

Justin J Stark
quelle
4

Alternativ können Sie versuchen, Ausnahmen zu testen, die tatsächlich mit den nächsten 2 Zeilen in Ihrem Test ausgelöst werden.

var testDelegate = () => MyService.Method(params);
Assert.Throws<Exception>(testDelegate);
Matias
quelle
4

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:

[TestMethod]
[ExpectedException(typeof(Exception), AllowDerivedTypes = true)]
public void ThrowExceptionTest()
{
    //...
}
TTT
quelle
3

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 ...

/// <summary>
/// Checks to make sure that the input delegate throws a exception of type TException.
/// </summary>
/// <typeparam name="TException">The type of exception expected.</typeparam>
/// <param name="methodToExecute">The method to execute to generate the exception.</param>
public static void AssertRaises<TException>(Action methodToExecute) where TException : System.Exception
{
    try
    {
        methodToExecute();
    }
    catch (TException) {
        return;
    }  
    catch (System.Exception ex)
    {
        Assert.Fail("Expected exception of type " + typeof(TException) + " but type of " + ex.GetType() + " was thrown instead.");
    }
    Assert.Fail("Expected exception of type " + typeof(TException) + " but no exception was thrown.");  
}
Roeiba
quelle
2

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.

[ExpectedException(typeof(ArgumentException))]
Jay
quelle
2

Versuchen Sie bei Verwendung von NUnit Folgendes :

Assert.That(() =>
        {
            Your_Method_To_Test();
        }, Throws.TypeOf<Your_Specific_Exception>().With.Message.EqualTo("Your_Specific_Message"));
Amir Chatrbahr
quelle
2

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:

    [Test]
    public void given_when_then()
    {
        Check.ThatCode(() => MethodToTest())
            .Throws<Exception>()
            .WithMessage("Process has been failed");
    }
mirind4
quelle
1

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();oder returnvon 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.

[TestMethod]
public void Bar_InvalidDependency_ThrowsInvalidOperationException()
{
    // Expectations
    InvalidOperationException expectedException = null;
    string expectedExceptionMessage = "Bar did something invalid.";

    // Arrange
    IDependency dependency = DependencyMocks.Create();
    Foo foo = new Foo(dependency);

    // Act
    try
    {
        foo.Bar();
    }
    catch (InvalidOperationException ex)
    {
        expectedException = ex;
    }

    // Assert
    Assert.IsNotNull(expectedException);
    Assert.AreEqual(expectedExceptionMessage, expectedException.Message);
}
Adam Venezia
quelle