2012-11-28 10 views
8

Quando un'eccezione non rilevata viene generata nel mio codice, sono abituato ad arrestare il debugger all'istruzione di lancio in modo da poter esaminare le variabili locali e i membri di tutti gli oggetti coinvolti nel momento in cui è stata lanciata l'eccezione. Con IntelliJ IDEA questo può essere realizzato andando a Run, View punti di interruzione, selezionando il eccezione punti di interruzione scheda, controllando Eventuali eccezioni, e fare in modo che il Preso casella di eccezione non è selezionata, mentre il La casella di controllo Eccezione non rilevata è selezionata. Con Eclipse e con Visual Studio (per C#) è qualcosa di diverso, ma lungo le stesse linee.JUnit 4 e Suspend-on-Exception

La possibilità di avere il debugger si comporta in questo modo è estremamente utile; così utile, infatti, che strutturo il ciclo principale dei miei programmi di conseguenza: nella versione di rilascio, il ciclo principale è ovviamente incorporato in un try-catch-all; ma nella versione di debug, non vi è alcun blocco try-catch nel ciclo principale, in modo che eventuali eccezioni che non vengono catturate da nessuna parte all'interno del mio programma rimarranno non archiviate, in modo che il debugger sospenda il mio programma nel momento in cui vengono lanciati.

Durante il test delle mie classi Java con JUnit, tuttavia, ho un problema: il debugger non si ferma su nessuna eccezione. Invece, ciò che accade è che non solo ci si aspetta, ma anche le eccezioni impreviste vengono catturate automaticamente, e mi viene data una traccia dello stack delle eccezioni post-mortem per cercare di capire. Non è molto bello.

Ho usato a pensare che questo sta accadendo perché JUnit fa uso di java.lang.reflect.Method.invoke(), che cattura tutte le eccezioni e li trasforma a TargetInvocationExceptions, ma poi ho scritto il mio corridore JUnit personalizzato, che conosce la mia classe di test personalmente e richiama direttamente i suoi metodi senza Method.invoke() e il problema persiste. Ciò significa che il problema si trova in alto nel core JUnit.

Quindi, qualcun altro ha lo stesso problema? Qualcuno sa di una soluzione in modo che il debugger possa sospendere l'esecuzione del programma su eccezioni impreviste durante il test con JUnit?

correlati (senza risposta) domanda: Suspend on uncaught runtime exceptions in Eclipse Junit test runner

correlati (senza risposta) domanda: How to break into debugger within a jUnit test case?

correlati (in parte risposto) domanda: Break on Exception in Eclipse using jUnit (La risposta accettata dice che "se si esegue il debug di un unico metodo di JUnit, i punti di interruzione iniziano a funzionare: se un'intera classe o un pacchetto è debug in jUnit, il debugger non funziona. ")

+0

Quale versione di JUnit è in esecuzione? Sono in grado di rilevare eccezioni non rilevate nei miei test, Eclipse Indigo Build 20110615-0604, JUnit 4. – Perception

+2

Sto usando JUnit 4.8.1. Si noti che questa domanda non riguarda la cattura di eccezioni non rilevate; Si tratta di fare in modo che il debugger sospenda l'esecuzione del programma su eccezioni non rilevate. In altre parole, si tratta di avere l'istruzione 'throw' che si comporta come un punto di interruzione se l'eccezione generata non è considerata. –

+0

Immagino di non essere stato chiaro. Il mio IDE (Eclipse Indigo), sospende l'esecuzione automaticamente, se lo dico anche io, sulle eccezioni pescate/non catturate. Anche quando si esegue un test JUnit 4. – Perception

risposta

0

Come soluzione temporanea da utilizzare per indagare su un errore di test, è possibile creare un'istanza del test incriminato classe nel metodo principale e chiamata il suo metodo di prova a mano con il metodo del tuo punto di rottura delle eccezioni (che è molto bello tra l'altro, grazie per la domanda). In questo modo, il metodo non viene chiamato in modo riflessivo.

+2

Grazie per la risposta, ma come dici tu, questa non è una soluzione reale, è una soluzione alternativa. In effetti, è più facile andare sulla linea dove è stata lanciata l'eccezione, (facendo clic sulla traccia dello stack,) posizionare un punto di interruzione lì e rieseguire. Voglio solo evitare di doverlo fare. –

1

spero ho capito correttamente alla domanda, quindi mi corregga se sbaglio, ma:

  • si dispone di un test, che genera un'eccezione, che non si cattura te stesso (in modo che, in questo senso, è non rilevata)
  • durante il debug di questo test con il testrunner JUnit4, JUnit si mostra che il test fallisce (che ha generato l'eccezione)
  • ma il filo non è sospeso, che è ciò che si vuole raggiungere
  • anche se è stato abilitato il preferences | java | debug | suspend execution on uncaught exceptions

In questo caso, credo che questo sia il comportamento previsto, le catture JUnit e ingoia il tuo eccezione, quindi non è non rilevata per quanto eclissi è interessato, come descritto qui https://bugs.eclipse.org/bugs/show_bug.cgi?id=414133

Si può avere eclissi sospendere in qualsiasi modo impostando le proprie regole per la sospensione delle eccezioni rilevate. Debug perspective | breakpoint view | J! icon | check suspend on caught exception

+0

La tua comprensione della domanda è corretta. Tuttavia, la soluzione proposta non funzionerà perché vengono lanciate migliaia di eccezioni (che vengono rilevate), sia nel codice di cui non ho il controllo, sia nel mio codice in normali operazioni, e anche nel mio codice allo scopo di testare il codice. controllo degli errori e gestione del codice. –

+0

Non riesco nemmeno ad usare i filtri di classe per occuparmi almeno delle eccezioni che vengono lanciate e catturate dal runtime java, perché a volte le eccezioni generate dal runtime Java si propagano al mio codice, e vorrei che il debugger si interrompesse proprio lì dove il codice richiama il metodo runtime che ha gettato, ma i debugger java apparentemente non hanno la nozione di "irrompe nel mio codice solo" come fa Microsoft Visual Studio. –

+0

Ah sì, ho capito, e dato il link che ho postato credo che la tua ultima frase sia corretta, il debugger di Eclipse non sembra avere la nozione di sospendere solo nel tuo codice. Questo sembra lasciare JUnit a non ingoiare le eccezioni come unica opzione ... Non ho idea se sia possibile ... – Hirle