VSTS Unit Test e Gestione Eccezioni
Gli Unit Test creati con VSTS consentono di dichiarare il fallimento dell'operazione andando a testare tramite la classe Assert i valori di ritorno di una chiamata a un metodo.
Spesso però il codice da testare potrebbe correttamente intercettare un'eccezione e scatenare un'eccezione applicativa. Un metodo di accesso ai dati ad esempio potrebbe intercettare un SqlException a fronte di problemi con il database e scatenare una DevLeap Exception che lo strato Biz o UI andrà a gestire. Ci sono due metodologie per testare correttamente la gestione delle eccezioni.
1) Nel metodo di Test si inserisce un Try/Catch e si agisce di conseguenza
Ad esempio potremmo fare questo
[TestMethod]
public void ListTest()
{
SalamiDal target = new SalamiDal();
try
{
target.List();
// Eventuali test con Assert.
}
catch (DevLeapException ex)
{
// Non fare niente: l'eccezione è stata correttamente scatenata
}
}
PS Prima che vi domandate perchè sto testando una roba che si chiama SalamiDal sappiate che si tratta di un'applicazione di Gestione Salumeria :-)
2) Il secondo metodo da usare su test molto specifico è indicare sul test tramite l'attributo ExpectedException l'eccezione che ci aspettiamo. Questa seconda strada evita la scrittura del blocco try/catch e fa sì che il test vada a buon fine solo se SalamiDal nel nostro caso scateni l'eccezione indicata.
Ad esempio il codice precedente potrebbe essere riscritto così:
[TestMethod]
[ExpectedException(typeof(SalamiManagement.Exceptions.DevLeapDBException))]
public void ListTest()
{
SalamiDal target = new SalamiDal();
try
{
target.List();
// Eventuali test con Assert.
}
catch (DevLeapException ex)
{
// Non fare niente: l'eccezione è stata correttamente scatenata
}
}
In questo caso il test da esito positivo se il metodo List di SalamiDal scatena un'eccezione di tipo SalamiManagement.Exceptions.DevLeapDBException. Con questa seconda modalità possiamo aspettarci una sola eccezione per ogni metodo di test, quindi il tutto è meno elastico rispetto al codice del primo esempio in cui potremmo intercettare diverse tipologie di eccezioni, scrivere costrutti condizionali per testare diverse cose.
Ultima nota: per testare ad esempio un fallimento di una Open di una DBConnection occorrerebbe modificare il file app.config del progetto test per poi riportarla ai valori corretti per testare il corretto funzionamento con la connessione corretta, oppure stoppare SQL Server, oppure negare l'accesso all'utente.
Visto che però i progetti VS non costano niente :-), perchè non creare un secondo progetto di test in cui inserire i test per gestire le eccezioni sul database: in questo modo avremmo sempre a disposizione sia il test che riesce a usare il db e il progetto che invece non riesce ad aprire la connessione. Sarà sufficiente indicare due connection string diverse nei due progetti e lanciando i test verificheremo entrambe le possibilità.
Personalmente creo sempre due progetti di test per ogni progetto da testare, il primo che testa il corretto funzionamento in condizioni normali, il secondo con un config volutamente sbagliato per testare le varie condizioni di gestione eccezioni.