2013-08-14 3 views
7

Ich habe ein Objekt als Ergebnis eines API-Aufrufs und ich möchte die Werte einer Member-Variable bestätigen.Ist es eine gute Idee, AssertionError in JUnit-Tests zu fangen?

Dieser Wert kann einer der zwei erwarteten Werte sein, abhängig davon, was der API-Aufruf zuerst sieht und setzt. Wenn also die Assertion für einen Wert fehlschlägt, möchte ich einen anderen Wert angeben, bevor der Test als Fehler deklariert wird.

Was ist der beste Weg, dies zu tun? Was ich gerade habe ist:

try { 
    assertEquals("message", someObject.getValue1(), expectedValue1); 
} catch(AssertionError ae) { 
    assertEquals("message", someObject.getValue1(), expectedValue2); 
} 

Ich bin nur nicht sicher, ob dies eine akzeptable Praxis ist. Bitte kommentieren.

Antwort

7

Die Verwendung von Ausnahmen als eine Art verherrlichte goto-Anweisung ist im Allgemeinen keine gute Übung. Oder zumindest werden Sie auf Leute in Ihrer Karriere stoßen, die die Verwendung von Ausnahmen für die Programmflusskontrolle ablehnen.

Wie wäre:

Assert.assertTrue((someObject.getValue1().equals(expectedValue1) || (someObject.getValue2().equals(expectedValue2)); 
+0

Danke, @Aquilon! In diesem Fall sind meine Behauptungen in einer Überprüfungsmethode verborgen, die als Parameter die Eigenschaften des Objekts annimmt, für das ich Geltendmachen muss. Daher kann ich zwei erwartete Werte für dieselbe Eigenschaft nicht wirklich übergeben, ohne die Signatur der Methode zu ändern. Also bleibe ich beim ursprünglichen Versuch ... Lösung zu fangen, während ich Ihre Lösung für die Zukunft notiere. – Shine

1

ich mit Aquilon bezüglich dieser nicht guter Praxis zustimmen werde.

Können Sie jedoch Spott oder einen anderen Mechanismus verwenden, um die API zu "zwingen", ein Element vor dem anderen zu "sehen"? Auf diese Weise können Ihre Tests die Bedingungen widerspiegeln, die dazu führen, dass eine Aussage in einem Test wahr ist und die andere Aussage in einem anderen Test wahr ist.

5

Hängt vom Zweck ab, automatisierte Funktionstests oder Komponententests. Ich mache das manchmal für die ehemaligen:

try { 
    assertTrue(boolean condition from earlier in test method to check); 
} 
catch(AssertionError uhOh) { 
    Logger.err("condition X failed: detailed info msg"); // broken item #1 

} 

try { 
    assertTrue(another condition in same method to check); 
} 
catch(AssertionError yuck) { 
    Logger.err("condition X failed: detailed info msg"); // another broken item 
    fail(); // now blow up as we've checked everything 
} 

Natürlich, die logback Logger und JUnit Assert.fail mit ist(), die das Testverfahren versagt. Auf diese Weise kenne ich alle Fehler für diese Methode, anstatt nach der ersten zu explodieren. In meinem Fall teste ich eine Rich-Content-Web-App (Dialoge und Seiten, die eine Menge Benutzereingaben erfordern).

Der Nachteil von "fail-fast" (ohne Fänge) ist ein Problem zu finden, es zu beheben, wieder zu laufen und einen neuen zu finden ("spülen und wiederholen"), aber wenn für Unit-Tests verwendet wird, ist dies ein Vermögenswert zur Modularität der Tests (im Idealfall testen Sie nur einen Aspekt eines Artikels pro Test).

Verwandte Themen