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


14

Capisco come funzionano le eccezioni e come catturarle e gestirle in C #, ma come posso simulare eventi che possono causare un'eccezione per garantire che vengano catturati 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 codice sia in grado di affrontarle.

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


Un'altra possibile soluzione è descritta in questo articolo MSDN: Test di iniezione di guasti con TestApi
Giorgi

Risposte:


13

1) Se seguissi il modello di iniezione di dipendenza, potresti sostituire le reali implementazioni di alcune parti con le beffe che genererebbero eccezioni quando ne hai bisogno. Ciò richiederebbe tuttavia all'utente di progettare inizialmente l'applicazione in un modo specifico o riprogettarla completamente.

Piace:

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 occuparsi della gestione di eccezioni concrete di implementazione.

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

Invece di:

FileStream fs = File.OpenRead (path);

usate:

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 ();
}

3

Devi guardare a quadri beffardi.

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 viene chiamato genera semplicemente l'eccezione desiderata:

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

Il test ha esito positivo quando il codice lo gestisce correttamente.


3

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

Se non vuoi riprogettare la tua app per adattarla a un framework di test, ciò di cui hai veramente bisogno è un host o un ambiente truccato per errori. Esistono molti modi per simulare la lentezza della rete della nostra interruzione (anche gli strumenti di test Microsoft hanno un po 'di questo nell'area di test Web). Ho avuto il massimo successo nel mettere le macchine dietro un router che può essere manomesso per cambiare le simulazioni in coordinamento con un set di database per produrre errori e script per cambiare gli errori che il database produce.

Anche con questo se vai abbastanza veloce o abbastanza in basso verso l'hardware ci sono errori come problemi di concorrenza e errori di scrittura ritardati che non puoi praticamente simulare. A volte devi causarli per davvero e altre volte devi solo lavorare senza la rete di sicurezza.


D'accordo: in alcuni casi, ad esempio, non è possibile permettersi le spese generali derivanti dall'iniezione di dipendenza nel codice di rilascio. Non è un problema quotidiano, ma può succedere.
Steve314,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.