2009-09-26 14 views
8

ho questo metodo nella mia classe di accesso ai dati e ho un test unitario per assicurarmi che funzioni correttamente, ma il mio test non verifica l'eccezione, quindi la mia domanda è: devo creare un nuovo test per forzare l'eccezione sollevato o devo semplicemente fidarmi che il blocco catch funzionerà bene in caso di un'eccezione? vale la pena?Devo forzare le eccezioni a metterle alla prova?

Ecco un esempio:

public void UpdateProject(Project project) 
    { 
     using (var transaction = _session.BeginTransaction()) 
     { 
      try 
      { 
       _session.Update(project); 
       _session.Flush(); 
       transaction.Commit(); 
      } 
      catch (HibernateException) 
      { 
       transaction.Rollback(); 
       throw; 
      } 
     } 
    } 

risposta

11

Idealmente, si dovrebbe cercare di testare ogni riga di codice che si può ... Ciò significherebbe costringere un'eccezione a verificarsi per testare il gestore di eccezioni, e assicurarsi questo funziona correttamente

In pratica, ci saranno sempre alcune righe di codice non coperte - tuttavia, forzerei le eccezioni via mocking per testare qualsiasi gestore di eccezioni che ritenete sia particolarmente critico, o che possa accadere in produzione.

+5

È sempre divertente eseguire il debug di un problema di produzione in cui l'arresto si trova nel blocco catch – Mark

+2

Se si tratta solo di logging e rethrowing, non mi preoccuperei. Probabilmente. Finché stavo testando la registrazione altrove. Se sta facendo qualcosa di importante, lo farei. – serialhobbyist

+2

Sì, anche se il rollback di una transazione può essere (non sempre) un processo piuttosto pesante, che a mio avviso dovrebbe essere testato. In questo caso, probabilmente lo testerei. –

3

È possibile ottenere una sessione in cui si fa finta di lanciare un'eccezione, ma non è necessario verificare che funzioni.

Non è sbagliato scrivere un test per verificare il rollback di una transazione se un aggiornamento genera un'eccezione, ma a livello di intestino penso che ciò stia andando troppo lontano.

Forse un caso più elaborato lo giustificherebbe.

Su una nota in più, non si desidera eseguire il rollback su alcun tipo di eccezione?

1

Dal nome dell'eccezione (HibernateException), penserei che non si tratti di un caso eccezionale. Quindi può succedere durante il normale funzionamento. In tal caso, eseguo un test che fa in modo che l'eccezione si assicuri che venga gestita correttamente.

9

Nel kernel di Linux, l'80% degli errori nei driver sono nel codice di gestione degli errori.

La gestione eccezionale è la fonte di molti errori e sicuramente dovrebbe verificare tutti i percorsi di eccezione.

Ovviamente non è possibile testare ogni riga di codice. Ma la statistica dice che i programmatori prestano meno attenzione alla gestione delle eccezioni, quindi è necessario testarli accuratamente.

3

Spero che la transazione sia Rollback se Displose() viene chiamato prima di Commit(), quindi è necessario il blocco?

Come per gli altri casi, se la cattura fa di più basta semplicemente registrare il problema, penso che dovrebbe essere testato unitamente. Tuttavia, non lasciare che il fatto che non si possa fare il test delle quote di profitto ti impedisca di eseguire alcuni test unitari.

1

Proverei certamente ogni eccezione specifica che viene catturata e gestita. Almeno hai un percorso di esecuzione attraverso il tuo codice di gestione che dovrebbe darti un po 'di conforto che non accadrà nulla di strano quando/se mai incontrerai tale eccezione durante il runtime.

Ricordare, è solo necessario testare il codice che si desidera lavorare.

1

Spero davvero che testare separatamente transaction.Rollback() con i test che esauriscono tutte le possibili situazioni che si possono pensare. Tuttavia, a condizione che il test fosse esaustivo, probabilmente non mi preoccuperei di sollevare un'eccezione poiché non c'è nient'altro nel gestore.

4

Qui sono le mie regole per i test ideale di comportamento a rottura:

  • Se si utilizza dipendenze che potrebbero generare eccezioni, allora si dovrebbe includere unit test che rendono i vostri prende in giro di gettarle eccezioni.
  • Se in determinate condizioni il codice deve generare un'eccezione, è necessario includere i test di unità che configurano tali condizioni.

La prima permette di sapere che cosa il vostro codice si comporta come in Errore esterno, e spesso porta a ripensamenti su cosa fare. In tutte le situazioni è bello vedere cosa succede realmente. Il secondo si limita a mantenere ciò che prometti, per quanto riguarda gli errori che il tuo codice dovrebbe rilevare e considerare eccezionali. Non è diverso da testare altre funzionalità nel codice.

Prima di considerare completa la suite di test unitari, è necessario dare un'occhiata al codice codice di copertura del codice in prova. Per codice non banale, c'è quasi sempre un modo in cui il mio ramo di codice che i miei test di unità non coprono o, peggio, ha un comportamento che non ho inteso. Sorprendentemente spesso, la soluzione è rimuovere quel codice piuttosto che aggiungere altri test. Solo cruft lasciato alle spalle quando si vola prima.

Non sto dicendo necessariamente che si dovrebbe raggiungere una copertura del 100%, ma si dovrebbe fare un test dell'unità basata sulla copertura del codice perché è un modo più visivo per comprendere ed esporre i comportamenti del codice esistenti. Basta guardarlo per darti nuove idee su come effettuare il refactoring del codice per ottenere Single Responsibility Principle e Separation of Concerns.

Problemi correlati