mir ist gerade zum ersten Mal der Fall passiert, dass ich Code testen möchte, der seine Exception selbst handelt. D.h. ich weiß von außen gar nicht, ob etwas schief gegangen ist oder nicht. Ein Beispiel:
Java:
publicvoidinit(String filename){try{URL url =getClass().getResource(filename);XMLInputSource in =newXMLInputSource(url);// wirft IOException}catch(IOException e){(Fehlerbehandlung)}}
Ich kann die IOException nicht weitergeben, weil die Methode eine überschriebene Superklassen-Methode ist. In meinem jUnit-Test kann ich nun zwar die Methode aufrufen und auf der Console sehen, dass bei falschen Dateinamen die IOException geworfen wird. Mein Test läuft aber immer fröhlich durch, dabei soll er anzeigen, dass es ein Problem gab.
Gibt es eine Möglichkeit zu erkennen, dass mein Code einen Fehler geworfen und selbst behandelt hat?
Wenn der Code die Exception schluckt, kannst du nie wissen ob eine aufgetreten ist.
Du testest ja von aussen eine blackbox, vielleicht kannst du ja ein mock nutzen, aber nicht jeder Code lässt sich eben testen, dafür gibt es Vorraussetzungen.
Doch das geht mit AspectJ und das auch ohne den Code zu ändern; ist nur mit etwas mehr (Konfigurations-)Aufwand verbunden. Man kann die Ausführung des Exception Handlers abfangen und z. B. die Exception werfen bevor oder nachdem sie behandelt wird. Im Anhang ist ein Maven-Projekt, das das demonstriert. TODO's:
Das Code-Weaving nur im Test-Scope durchführen.
Den Aspekt in den Test-Codezweig verlagern.
Den Aspekt mittels
Code:
within()
genauer auf den Testfall abstellen.
Wenn der Quellcode der zu testenden Klasse im gleichen Build ist wie die Testklasse kannst Du das wie in der pom.xml machen. Wenn der Code in einem separaten Build läuft und Du nur ein JAR mit der Klasse hast, die die Exception behandelt, musst Du das maven-aspectj-Plugin so konfigurieren, das es JAR-Files weaved. (Kniffliger wird's, wenn die signiert sind...)
Der JUnit-Test soll im Idealfall wahrscheinlich so aussehen:
Die eigentliche Frage ist hier doch, wieso möchtest du irgendwas von der Exception mitbekommen von außen.
Da die Methode den Fehler ja selber behandelt, müsste es doch einfach ein erwartetes Ergebnis für den Fehlerfall geben, z.B. die Rückgabe eines Defaultwertes. Also gibst du einfach Daten hinein, die den Fehler verursachen und testest anschließend ob der Defaultwert gesetzt ist (also die Fehlerbehandlung funktioniert hat).