2012-01-13 14 views
9

Come posso simulare un'eccezione generata nei test di unità C#?Come simulare il lancio di un'eccezione nei test unitari?

Desidero poter avere una copertura del 100% del mio codice, ma non riesco a testare il codice con eccezioni che possono verificarsi. Ad esempio, non posso simulare un potere faluire che può verificarsi.

Ad esempio:

public void MyMethod() 
{ 
    try 
    { 
    ... 
    } 
    catch(OutOfMemoryException e) 
    { 
    ... 
    } 
    catch(RandomErrorFromDatabaseLayer e) 
    { 
    ... 
    } 
} 

voglio essere in grado di simulare qualsiasi tipo di eccezione che è in questo metodo e deve essere catturato.
Esistono librerie che potrebbero aiutarmi in questa faccenda?

Modifica 1: Qualsiasi aiuto nel realizzare ciò che ho chiesto con Moq?

+1

Il tuo esempio di codice non spiega realmente il problema. Perché non riesci a simulare un black-out? Stai provando a "iniettare" le condizioni che potrebbero causare il lancio delle eccezioni citate? Qual è il vero problema? –

+0

sì, proprio come in http://stackoverflow.com/a/8851628/79379, ma senza che io distrugga un database per simulare un faluire del database. –

risposta

8

È necessario creare un oggetto fittizio che sostituisce gli oggetti reali che possono generare queste eccezioni. Quindi è possibile creare test che semplicemente sono qualcosa di simile:

public void ExampleMethod() 
{ 
    throw new OutOfMemoryException(); 
} 

Se si utilizza un quadro di iniezione di dipendenza rende sostituendo il codice vero e proprio con il codice finto molto più facile.

5

Quello che ti serve è stub - un oggetto che simulerà determinate condizioni per il tuo codice. A scopo di test, di solito sostituisci l'implementazione di oggetti reali con stub (o altri tipi di oggetti simulati). Nel tuo caso, prendere in considerazione:

public class MyClass 
{ 
    private IDataProvider dataProvider; 

    public void MyMethod() 
    { 
     try 
     { 
      this.dataProvider.GetData(); 
     } 
     catch (OutOfMemoryException) 
     { 
     } 
    } 
} 

Ora, classe che si sta testando dovrebbe essere configurabile a un certo livello - in modo che si può facilmente sostituire reale DataProvider implementazione con contuso/falsificate uno quando il test (come hai detto tu, è don' Voglio distruggere il tuo DB - nessuno vuole!). Ciò può essere ottenuto ad esempio mediante iniezione del costruttore (o, in effetti, qualsiasi altra tecnica dependency injection).

Il test, allora è banale (qualche requisito truccata per verificare quando viene generata un'eccezione):

[Test] 
public void MyMethod_DataProviderThrowsOutOfMemoryException_LogsError() 
{ 
    var dataProviderMock = new Mock<IDataProvider>(); 
    dataProviderMock 
     .Setup(dp => dp.GetData()) 
     .Throws<OutOfMemoryException>(); 
    var myClass = new MyClass(dataProviderMock); 

    myClass.MyMethod(); 

    // assert whatever needs to be checked 
} 
Problemi correlati