2012-11-28 8 views
8

Wenn eine nicht abgefangene Ausnahme in meinem Code ausgelöst wird, bin ich es gewohnt, den Debugger bei der Anweisung werfen zu lassen, so dass ich die lokalen Variablen und die Mitglieder aller beteiligten Objekte untersuchen kann Moment, dass die Ausnahme ausgelöst wurde. Mit IntelliJ Idea dies kann, Ansicht Haltepunkte, die Auswahl der Ausnahme, indem Sie auf Run erreicht werden Haltepunkte Registerkarte Überprüfung Jede Ausnahme, und sicherstellen, dass die Exception abgefangen Checkbox deaktiviert ist, während die Nicht abgefangene Ausnahme Kontrollkästchen ist aktiviert. Mit Eclipse und mit Visual Studio (für C#) ist es etwas anderes, aber in gleicher Weise.JUnit 4 und Suspend-on-Exception

Die Fähigkeit, den Debugger auf diese Weise zu verhalten, ist äußerst nützlich. so nützlich in der Tat, dass ich die Hauptschleife meiner Programme entsprechend strukturiere: In der Release-Version ist die Hauptschleife natürlich in einen try-catch-all eingebettet; Aber in der Debug-Version gibt es keinen try-catch-Block in der Hauptschleife, so dass alle Ausnahmen, die nirgends in meinem Programm abgefangen werden, nicht abgefangen werden, so dass der Debugger mein Programm in dem Moment, in dem sie ausgelöst werden, aussetzt.

Beim Testen meiner Java-Klassen mit JUnit habe ich jedoch ein Problem: Der Debugger stoppt bei keiner Ausnahme. Was passiert, ist, dass nicht nur erwartete, sondern auch unerwartete Ausnahmen automatisch abgefangen werden und dass mir eine Post-Mortem-Ausnahme-Stack-Ablaufverfolgung gegeben wird, um zu versuchen, Sinn zu machen. Das ist nicht sehr cool.

Früher dachte ich, dass dies geschieht, weil JUnit Verwendung von java.lang.reflect.Method.invoke() macht, der alle Ausnahmen abfängt und transformiert sie in TargetInvocationExceptions, aber dann meine eigene benutzerdefinierte JUnit runner ich schrieb, die persönlich meine Testklasse kennt und ruft direkt ihre Methoden ohne Method.invoke(), und das Problem besteht fort. Dies bedeutet, dass das Problem innerhalb von Core JUnit weit oben liegt.

Also, hat jemand anderes das gleiche Problem? Kennt jemand eine Lösung, damit der Debugger die Programmausführung bei unerwarteten Ausnahmen anhalten kann, während er mit JUnit testet?

Verwandte (offen) Frage: Suspend on uncaught runtime exceptions in Eclipse Junit test runner

Verwandte (offen) Frage: How to break into debugger within a jUnit test case?

Verwandte (teilweise beantwortet) Frage: Break on Exception in Eclipse using jUnit (Die akzeptierte Antwort sagt, dass „wenn Sie Debug für eine einzelne Methode in jUnit, Die Breakpoints beginnen zu arbeiten. Wenn eine ganze Klasse oder ein ganzes Paket in jUnit debuggt wird, funktioniert der Debugger nicht. ")

+0

In welcher Version von JUnit laufen Sie? Ich kann nicht abgefangene Ausnahmen in meinen Tests gut fangen, Eclipse Indigo Build 20110615-0604, JUnit 4. – Perception

+2

Ich benutze JUnit 4.8.1. Bitte beachten Sie, dass es bei dieser Frage nicht darum geht, nicht abgefangene Ausnahmen zu erfassen. Es geht darum, dass der Debugger die Programmausführung bei nicht abgefangenen Ausnahmen anhält. Mit anderen Worten, es geht darum, dass sich die Anweisung "throw" wie ein Breakpoint verhält, wenn die geworfene Exception nicht abgefangen wird. –

+0

Ich denke, ich war nicht klar. Meine IDE (Eclipse Indigo) unterbricht die Ausführung automatisch, wenn ich es auch erzähle, bei gefangenen/nicht abgefangenen Ausnahmen. Selbst wenn Sie einen JUnit 4 Test durchführen. – Perception

Antwort

0

Als Workaround zur Untersuchung eines Testfehlers können Sie eine Instanz des problematischen Tests erstellen Klasse in Hauptmethode und Aufruf seine Testmethode von Hand mit Ihrer Ausnahme Breakpoints-Methode (die übrigens sehr cool ist, danke für die Frage). Auf diese Weise wird die Methode nicht reflektiv aufgerufen.

+2

Vielen Dank für die Antwort, aber wie Sie sagen, dies ist keine echte Lösung, es ist ein Workaround. In der Tat ist es einfacher, einfach zu der Zeile zu gehen, in der die Ausnahme ausgelöst wurde (indem Sie auf die Stack-Ablaufverfolgung klicken), dort einen Haltepunkt platzieren und erneut ausführen. Ich möchte einfach vermeiden, dass ich das tun muss. –

1

Ich hoffe, dass ich die Frage richtig verstanden habe, mich so korrigieren, wenn ich falsch bin, aber:

  • Sie einen Test haben, die eine Ausnahme auslöst, die Sie nicht selbst fangen (so ist es, in dass Sinn ist nicht abgefangene)
  • , wenn Sie diesen Test mit dem testrunner JUnit4 debuggen, JUnit Sie zeigt, dass der Test nicht besteht (es die Ausnahme ausgelöst hat)
  • aber der Faden nicht unterbrochen ist, das ist, was Sie
  • erreichen wollen
  • obwohl Sie preferences | java | debug | suspend execution on uncaught exceptions aktiviert haben

In diesem Fall glaube ich, das das beabsichtigte Verhalten ist, JUnit Fänge und schluckt Ihre Ausnahme, so ist es so weit nicht abgefangene als Eclipse betrifft, so https://bugs.eclipse.org/bugs/show_bug.cgi?id=414133

Sie haben Eclipse können hier beschrieben suspendieren in jedem Fall, indem Sie Ihre eigenen Regeln für das Aussetzen von abgefangenen Ausnahmen festlegen. Debug perspective | breakpoint view | J! icon | check suspend on caught exception

+0

Ihr Verständnis der Frage ist richtig. Ihre vorgeschlagene Lösung wird jedoch nicht funktionieren, da Tausende von Ausnahmen (die abgefangen werden) sowohl in Code, auf den ich keinen Einfluss habe, als auch in meinem Code unter normalen Operationen und auch in meinem Code zum Testen des Fehlerprüf- und Bearbeitungscode. –

+0

Ich kann nicht einmal Klassenfilter verwenden, um wenigstens auf die Ausnahmen zu achten, die von der Java-Laufzeit ausgelöst und abgefangen werden, da manchmal von der Java-Laufzeitumgebung ausgegebene Ausnahmen zu meinem Code propagieren, und ich möchte, dass der Debugger genau dort bricht code ruft die Laufzeitmethode auf, die warf, aber Java-Debugger haben offensichtlich keine Ahnung von "nur in meinem Code einbrechen" wie Microsoft Visual Studio. –

+0

Ah ja, ich verstehe, und angesichts des Links, den ich gepostet habe, denke ich, Ihr letzter Satz ist korrekt, der Eclipse-Debugger scheint keine Vorstellung davon zu haben, nur in Ihrem Code zu suspendieren. Das scheint JUnit davon abzuhalten, Ihre Ausnahmen als einzige Option zu verschlucken ... Ich habe keine Ahnung, ob das möglich ist ... – Hirle