Wie kann ich mit einer bestimmten Ausnahmemeldung für eine erwartete Ausnahme teste aus einer Ressourcendatei in Visual Studio Test?

stimmen
39

Visual Studio-Test kann für die erwarteten Ausnahmen überprüfen Sie das ExpectedException Attribut. Sie können in Ausnahmefällen wie folgt übergeben:

[TestMethod]
[ExpectedException(typeof(CriticalException))]
public void GetOrganisation_MultipleOrganisations_ThrowsException()

Sie können auch für die in der ExpectedException wie dies enthaltene Nachricht überprüfen:

[TestMethod]
[ExpectedException(typeof(CriticalException), An error occured)]
public void GetOrganisation_MultipleOrganisations_ThrowsException()

Aber beim Testen L18N Anwendungen würde ich eine Ressource-Datei verwenden, um diese Fehlermeldung zu erhalten (jeder kann selbst entscheiden, die verschiedenen Lokalisierungen der Fehlermeldung zu testen, ob ich will, aber Visual Studio wird mir das nicht tun lassen:

[TestMethod]
[ExpectedException(typeof(CriticalException), MyRes.MultipleOrganisationsNotAllowed)]
public void GetOrganisation_MultipleOrganisations_ThrowsException()

Der Compiler wird den folgenden Fehler geben:

Ein Attribut Argument ist ein konstanter Ausdruck, Typeof Expression oder Expression Array Schaffung eines Attributs sein

Weiß jemand, wie eine Ausnahme zu testen, die eine Nachricht von einer Ressourcendatei hat?


Eine Option, die ich habe in Betracht gezogen wird, mithilfe von benutzerdefinierten Ausnahmeklassen, sondern auf der Grundlage oft gehörten Ratschlägen wie:

„Erstellen und benutzerdefinierte Ausnahmen auslösen , wenn Sie einen Fehler haben , die programmatisch in einer anderen Art und Weise als jede andere bestehende Ausnahme behandelt werden können. Andernfalls eine der bestehenden Ausnahmen werfen.“ Quelle

Ich bin nicht die Ausnahmen unterschiedlich im normalen Fluss zu behandeln erwartet (es ist eine kritische Ausnahme, also werde ich in Panik-Modus sowieso), und ich glaube nicht, eine Ausnahme für jeden Testfall zu schaffen ist das Richtige zu tun. Alle Meinungen?

Veröffentlicht am 22/09/2008 um 07:08
quelle vom benutzer
In anderen Sprachen...                            


7 antworten

stimmen
63

Ich würde empfehlen, eine Hilfsmethode statt ein Attribut verwenden. Etwas wie das:

public static class ExceptionAssert
{
  public static T Throws<T>(Action action) where T : Exception
  {
    try
    {
      action();
    }
    catch (T ex)
    {
      return ex;
    }
    Assert.Fail("Exception of type {0} should be thrown.", typeof(T));

    //  The compiler doesn't know that Assert.Fail
    //  will always throw an exception
    return null;
  }
}

Dann können Sie Ihren Test so etwas schreiben:

[TestMethod]
public void GetOrganisation_MultipleOrganisations_ThrowsException()
{
  OrganizationList organizations = new Organizations();
  organizations.Add(new Organization());
  organizations.Add(new Organization());

  var ex = ExceptionAssert.Throws<CriticalException>(
              () => organizations.GetOrganization());
  Assert.AreEqual(MyRes.MultipleOrganisationsNotAllowed, ex.Message);
}

Dies hat auch den Vorteil, dass es überprüft, ob die Ausnahme auf der Linie geworfen wird man es erwartet hatte in der Testmethode statt überall geworfen werden.

Beantwortet am 22/09/2008 um 08:26
quelle vom benutzer

stimmen
13

Das ExpectedException Nachricht Argument nicht gegen die Meldung der Ausnahme. Vielmehr ist dies die Botschaft, die in den Testergebnissen werden gedruckt, wenn die erwartete Ausnahme nicht auftritt in der Tat.

Beantwortet am 16/01/2009 um 06:40
quelle vom benutzer

stimmen
7

Nur eine Meinung, aber ich würde den Fehlertext sagen:

  • Teil des Tests ist es, in diesem Fall ist es von der Ressource bekommen wäre ‚falsch‘ (sonst Sie mit einer consistantly verstümmelten Ressource könnten am Ende), so aktualisieren Sie einfach den Test, wenn Sie die Ressource zu ändern (oder der Test nicht bestanden)
  • ist nicht von dem Testteil, und Sie sollten nur darauf, dass es die Ausnahme auslöst.

Beachten Sie, dass die erste Option sollten Sie mehrere Sprachen, da die Fähigkeit zu laufen mit einem locale testen lassen.

Wie für mehrere Ausnahmen, ich bin von C ++ Land, wo viele, viele Ausnahmen (bis zu dem Punkt eines pro ‚werfen‘ Aussage!) In großen heirachies schaffen, ist akzeptabel (wenn nicht üblich), aber wahrscheinlich Metadatensystem .Net doesn ‚t so, damit, dass die Beratung.

Beantwortet am 22/09/2008 um 07:28
quelle vom benutzer

stimmen
4

Ich denke, man kann nur einen expliziten try-catch in Ihrem Test-Code tun, anstatt auf dem ExpectedException Attribute verläßt es für Sie zu tun. Dann können Sie mit einiger Hilfsmethode kommen, die die Ressourcendatei und vergleichen Sie die Fehlermeldung zu dem einen werden gelesen, dass mit Ausnahme kommt, die gefangen wurde. (Natürlich, wenn es nicht eine Ausnahme dann sollte der Testfall ein nicht berücksichtigt)

Beantwortet am 22/09/2008 um 07:15
quelle vom benutzer

stimmen
3

Wenn Sie das sehr schön wechseln zu verwenden xUnit.Net Test Bibliothek können Sie ersetzen [ExpectedException] mit etwas wie folgt aus :

[Fact]
public void TestException()
{
   Exception ex = Record.Exception(() => myClass.DoSomethingExceptional());
   // Assert whatever you like about the exception here.
}
Beantwortet am 22/09/2008 um 07:15
quelle vom benutzer

stimmen
1

Ich frage mich, ob NUnit ist der Weg weg von der Einfachheit nach unten bewegen ... aber hier geht.

Neue Erweiterungen (2.4.3 oder höher) zu der ExpectedException Attribut Sie mehr Kontrolle über die Kontrollen ermöglichen , sich auf die erwartete Ausnahme über eine Handler - Methode durchgeführt werden . Weitere Details zu der offiziellen NUnit doc Seite .. am Ende der Seite.

[ExpectedException( Handler="HandlerMethod" )]
public void TestMethod()
{
...
}

public void HandlerMethod( System.Exception ex )
{
...
}

Hinweis: Etwas stimmt hier nicht fühlt .. Warum Nachrichten Ihre Ausnahmen internationalisiert sind .. Sind Sie Ausnahmen für Dinge verwenden, die behandelt werden müssen, oder dem Benutzer mitgeteilt. Es sei denn, Sie eine Reihe von kulturell unterschiedlichen Entwickler Fehler zu beheben haben .. Sie sollten dies nicht mehr brauchen. Ausnahmen in Englisch oder eine gemeinsame akzeptierte Sprache ausreichen würden. Aber für den Fall, müssen Sie dies haben .. its möglich :)

Beantwortet am 22/09/2008 um 07:46
quelle vom benutzer

stimmen
0

Ich kam in dieser Frage bei dem Versuch, ein ähnliches Problem auf eigene Faust zu lösen. (Ich werde Detail die Lösung, die ich auf unten angesiedelt.)

Ich habe mit Gishu Kommentare über internationalisieren die Ausnahmemeldungen sind ein Code Geruch zu vereinbaren.

Ich hatte dies zunächst in meinem eigenen Projekt getan, damit ich Konsistenz haben könnte zwischen den Fehlermeldungen von meiner Anwendung zu werfen und in meinen Unit-Tests. dh nur muss meine Ausnahmemeldungen an einem Ort und zu der Zeit definieren, schien die Ressource-Datei wie ein vernünftiger Ort dies, da ich tut schon war es für verschiedene Labels und Strings (und da es sinnvoll, einen Verweis hinzuzufügen in meinem Test-Code, um es zu überprüfen, ob die gleichen Etiketten an den entsprechenden Stellen gezeigt).

An einem Punkt hatte ich in Betracht gezogen (und getestet) unter Verwendung von try / catch-Blöcken die Anforderung eines konstanten durch das ExpectedException Attribut zu vermeiden, aber dies schien wie es eine ganze Menge zusätzlichen Code führen würde, wenn in großem Umfang angewandt.

Am Ende, dass die Lösung, die ich lasse dich auf war eine statische Klasse in meiner Ressource-Bibliothek zu erstellen und speichern meine Ausnahmemeldungen in diesen. Auf diese Weise gibt es keine Notwendigkeit, sie zu internationalisieren (was ich zustimmen werde keinen Sinn macht), und sie sind jederzeit zugänglich gemacht, dass eine Ressourcenzeichenfolge zugänglich sein würde, da sie im gleichen Namensraum sind. (Das paßt mit meinem Wunsch nicht der Ausnahme Text einen komplexen Prozess machen zu überprüfen.)

Mein Testcode dann kocht einfach nach unten zu (die Mangeln verzeihen ...):

[Test, 
    ExpectedException(typeof(System.ArgumentException),
    ExpectedException=ProductExceptionMessages.DuplicateProductName)]
public void TestCreateDuplicateProduct()
{
    _repository.CreateProduct("TestCreateDuplicateProduct");
    _repository.CreateProduct("TestCreateDuplicateProduct");
} 
Beantwortet am 18/02/2009 um 23:00
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more