2014-09-29 17 views
6

Ho scritto una classe di unit test in C# per il mio progetto MVC.Come gestire l'eccezione generata in NUnit

Il metodo di prova è seguito

[Test] 
    public void To_Add_DocumentStatusIsNull_ThrowsInvalidOperationException_ServiceTest() 
    { 
     try 
     { 

     _IDocumentStatusRepositoryMock = new Mock<IDocumentStatusRepository>(); 
     _unitOfWorkMock = new Mock<IUnitOfWork>(); 

     DocumentStatusService documentStatusService = new 
     DocumentStatusService(_unitOfWorkMock.Object, 
      _IDocumentStatusRepositoryMock.Object); 

     DocumentStatus documentStatus; 
     documentStatus = null; 

     _IDocumentStatusRepositoryMock.Setup(m => m.Add(documentStatus)); 
     documentStatusService.Add(documentStatus); 

     Assert.Pass(); 

     } 
     catch (Exception e) 
     { 
      throw new Exception(e.Message); 
     } 
    } 

e il metodo Servizio è seguito

public virtual void Add(TEntity entity) 
    { 
     try 
     { 

     if (entity == null) 
     { 
      throw new ArgumentNullException("entity"); 
     } 
     _repository.Add(entity); 

     } 
     catch (Exception e) 
     { 
      throw new Exception(e.Message); 
     } 
    } 

Ora solo non Questo metodo di test è stato superato a causa della classe di servizio gettato ArgumentNullException.So come gestire l'ArgumentNullException o come passare questo test?

Si prega chiunque aiutare

+3

qual è lo scopo di "lanciare una nuova eccezione (e.Message);" nel metodo di servizio? perché non lasci che venga sollevata l'eccezione originale? Non riesco a vedere alcun uso per quella configurazione 'try' /' catch' ...? E non c'è * certamente * nessun punto nel 'try' /' catch' nel test NUnit mostrato - NUnit considera automaticamente le eccezioni come errori, a meno che tu non abbia indicato un'eccezione nota nota –

+0

Mi dispiace, che è scritto per qualche altro scopo e tu sei giusto questo non è corretto. Ora voglio sapere come gestire l'ArgumentNullException nel mio metodo di prova? –

risposta

5

Se si sta tentando di controllare che il ArgumentNullException sta lavorando (che: non è attualmente). allora suona come si desidera:

[Test, ExpectedException(typeof(ArgumentNullException), ExpectedMessage = @"Value cannot be null. 
Parameter name: entity")] 
public void To_Add_DocumentStatusIsNull_ThrowsInvalidOperationException_ServiceTest() 
{ 
    _IDocumentStatusRepositoryMock = new Mock<IDocumentStatusRepository>(); 
    _unitOfWorkMock = new Mock<IUnitOfWork>(); 

    DocumentStatusService documentStatusService = new 
    DocumentStatusService(_unitOfWorkMock.Object, 
     _IDocumentStatusRepositoryMock.Object); 

    DocumentStatus documentStatus; 
    documentStatus = null; 

    _IDocumentStatusRepositoryMock.Setup(m => m.Add(documentStatus)); 
    documentStatusService.Add(documentStatus); 
} 

...

public virtual void Add(TEntity entity) 
{ 
    if (entity == null) 
    { 
     throw new ArgumentNullException("entity"); 
    } 
    _repository.Add(entity); 
} 
+0

Ho testato il tuo codice come sopra indicato ma non vengono apportate modifiche –

+0

Scusa Marc funziona !!!! –

+0

Grazie mille per la risposta –

1

Io parto dal presupposto: Guardando il codice di questo test unità non deve passare. Nella maggior parte dei casi, l'aggiunta di un NULL a un elenco non è un comportamento previsto.

Vedo 2 opzioni: A) È necessario aggiungere un try/catch a test Metodo.

try 
{ 
    _IDocumentStatusRepositoryMock.Setup(m => m.Add(documentStatus)); 
    documentStatusService.Add(documentStatus); 
} 
catch (Exception) 
{ 
    Assert.Fail(); // or nothing is expected behaviour 
} 

B) Rimuovere il blocco try/catch dal metodo di test in modo da non ingerire l'eccezione. (Ogni prova che non riesce o un'asserzione o thows un'eccezione unhandeled automaticamente passa)

+0

Sì, questo test unitario non deve passare, ma non so come comportarsi. E ho provato le tue soluzioni in modo tale che viene data sopra, non c'è nulla di cambiato.Per favore qualsiasi altra soluzione? –

-1

Test per l'ArgumentNullException

Se si rimuove il mal consigliato

catch (Exception e) 
{ 
    throw new Exception(e.Message); 
} 

dal codice a essere testato (l'attuale catch perde il contesto dell'errore e interrompe la traccia dello stack, vedere di seguito), il test può essere semplice come il wrapping dell'invocazione in un Assert.Throws<ArgumentNullException>():

[Test] 
public void PassingANullEntityToAddMustThrowArgumentNullException() 
{ 
    var documentStatusService = new DocumentStatusService(...); 
    Assert.Throws<ArgumentNullException>(() => documentStatusService.Add(null)); 
} 

Re: Il tuo gestore delle eccezioni

Nel codice di servizio, mai catturare un'eccezione e rigenerare come hai fatto, in quanto questo perderà la traccia dello stack (per esempio _repository.Add(entity); potrebbe lanciare anche.).Inoltre, non si aggiunge alcun valore lanciando e.Message come questo è già l'eccezione originale (con informazioni aggiuntive come stack trace e l'eccezione interna)

Bad:

catch (Exception e) 
    { 
     throw new Exception(e.Message); 
    } 

Meglio: se non cattura e rigenerare con un certo valore, avvolgere l'originale come eccezione interna:

catch (SqlException ex) 
{ 
    throw new Exception("Some value add here", ex); 
} 

o se sono solo intercettare e Consenti di propagare:

catch (SqlException) 
{ 
    // Do some logging 
    throw; 
} 

Meglio per me consentire l'propagazione dell'eccezione, a meno che tu non stia aggiungendo valore o gestendolo.