Come simulare eventi che causano eccezioni per testare i blocchi try / catch?

12

Capisco come funzionano le eccezioni e come catturarle e gestirle in C #, ma come posso simulare eventi che potrebbero causare un'eccezione per garantire che vengano rilevati correttamente? Ad esempio, è possibile eseguire un'applicazione in una sorta di banco di prova in cui è possibile simulare problemi di rete, problemi di database, ecc.? Le eccezioni per loro natura sembrano difficili da riprodurre, rendendo così difficile garantire che il tuo codice possa farcela.

Anche se sviluppo principalmente utilizzando C # /. NET / Visual Studio, le risposte o le risorse relative ad altri linguaggi potrebbero essere utili.

    
posta Piers Myers 08.02.2011 - 17:10
fonte

3 risposte

13

1) Se hai seguito il modello di iniezione delle dipendenze, potresti sostituire le reali implementazioni di alcune parti con i mock che genererebbero eccezioni a seconda delle tue esigenze. Ciò tuttavia richiederebbe a te inizialmente di progettare la tua applicazione in un modo specifico o di riprogettarla completamente.

Come:

public class SqlUsersRepository : IUsersRepository
{
    public void RegisterNewUser (User newUser)
    {
        throw new SqlException ("Connection timeout");
    }
}

Qui tuttavia avremmo il problema che il codice del consumatore non dovrebbe preoccuparsi di gestire le eccezioni di implementazione concreta.

2) Un altro approccio è quello di sostituire alcune chiamate di metodo con i wrapper personalizzati.

Invece di:

FileStream fs = File.OpenRead (path);

usi:

FileStream fs = File.OpenRead_Test (path);

fornendo un metodo di estensione personalizzato (solo un'idea rapida):

public static FileStream OpenRead_Test (this System.IO.File file, string path)
{
    throw new FileNotFoundException ();
}
    
risposta data 08.02.2011 - 17:16
fonte
3

Devi dare un'occhiata ai quadri di derisione.

Con questi usi l'iniezione delle dipendenze per chiamare il database falso (diciamo) piuttosto che quello reale. Ciò significa che hai il controllo totale su ciò che viene restituito per ogni chiamata.

Quindi si imposta un test che, quando chiamato, genera semplicemente l'eccezione desiderata:

public void Test1()
{
    throw new NullArgumentException();
}

Il test passa quando il codice lo gestisce correttamente.

    
risposta data 08.02.2011 - 17:17
fonte
3

La derisione e l'iniezione possono solo farti arrivare così lontano e richiedono grandi cambiamenti nell'approccio in alcuni casi.

Se non vuoi riprogettare la tua app per adattarla a un framework di test, ciò di cui hai realmente bisogno è un host o un ambiente truccato per errori. Esistono molti modi per simulare la lentezza della rete durante la nostra interruzione (anche gli strumenti di test di Microsoft hanno un po 'di questo nell'area di test del web). Ho ottenuto il miglior risultato con l'inserimento di macchine dietro un router che può essere manomesso per modificare le simulazioni in coordinamento con un set di database per produrre errori e script per modificare gli errori prodotti dal database.

Anche con questo se si va abbastanza velocemente o abbastanza verso l'hardware ci sono errori come problemi di concorrenza e errori di scrittura ritardati che non si può praticamente simulare. A volte devi causarli per davvero e altre volte devi solo lavorare senza la rete di sicurezza.

    
risposta data 08.02.2011 - 17:30
fonte

Leggi altre domande sui tag