2009-03-25 4 views
7

J'essaie de tester un ensemble de classes .NET qui (pour de bonnes raisons de conception) nécessitent que DbConnections fasse son travail. Pour ces tests, j'ai certaines données en mémoire à donner en entrée à ces classes.DbConnexion sans Db utilisant DataSet en mémoire (ou similaire) comme source

Cette donnée en mémoire peut être facilement exprimée en tant que DataTable (ou un DataSet qui contient ce DataTable), mais si une autre classe était plus appropriée, je pourrais l'utiliser. Si j'étais en quelque sorte magiquement capable d'obtenir une connexion DbConnection qui représentait une connexion aux données en mémoire, alors je pourrais construire mes objets, les faire exécuter leurs requêtes sur les données en mémoire, et m'assurer que leur sortie correspondait attentes. Existe-t-il un moyen d'obtenir une connexion DbConnection aux données en mémoire? Je n'ai pas la liberté d'installer un logiciel tiers supplémentaire pour que cela se produise, et idéalement, je ne veux pas toucher le disque pendant les tests.

Répondre

6

Plutôt que de consommer un DbConnection pouvez-vous consommer IDbConnection et se moquer de lui? Nous faisons quelque chose de similaire, passez le faux un DataSet. DataSet.CreateDataReader renvoie un DataTableReader qui hérite de DbDataReader.

Nous avons enveloppé DbConnection dans notre propre interface de type IDbConnection à laquelle nous avons ajouté une méthode ExecuteReader() qui retourne une classe qui implémente les mêmes interfaces que DbDataReader. Dans notre simulacre, ExecuteReader retourne simplement ce que DataSet.CreateDataReader sert.

Cela ressemble à un rond-point, mais il est très pratique de construire un DataSet avec éventuellement plusieurs jeux de résultats. Nous nommons les DataTables après les procs stockés qu'ils représentent les résultats de, et notre IDbConnection mock saisit la bonne Datatable en fonction du proc appelé par le client. DataTable implémente également CreateDataReader, donc nous sommes prêts à partir.

0

TypeMock? (Vous auriez besoin de 'l'installer' si).

Soyez prudent en supposant que Data * peut vous donner des crochets appropriés pour les tests - c'est plutôt le pire des cas en général. Mais vous dites bonnes raisons de conception, donc je suis sûr que tout est couvert: D

3

Une approche que j'ai utilisée est de créer une base de données Sqlite en mémoire. Cela peut être fait simplement en tirant le paquet System.Data.SQLite.Core NuGet à votre projet de test unitaire, vous n'avez pas besoin d'installer un logiciel ailleurs.

Bien que cela semble une idée vraiment évidente, ce n'est que lorsque j'ai regardé les tests unitaires Dapper que j'ai pensé utiliser la technique moi-même! Voir la méthode « GetSqliteConnection » dans

https://github.com/StackExchange/dapper-dot-net/blob/bffb0972a076734145d92959dabbe48422d12922/Dapper.Tests/Tests.cs

Une chose à prendre en compte est que si vous créez un en mémoire sqlite db et créer et alimenter des tables, vous devez faire attention de ne pas fermer la connexion avant effectuer vos requêtes de test car l'ouverture d'une nouvelle connexion en mémoire vous donnera une connexion à une base de données en mémoire nouvelle, pas la base de données que vous avez soigneusement préparé pour vos tests! Pour certains de mes tests, j'utilise une implémentation IDbConnection personnalisée qui maintient la connexion ouverte pour éviter ce piège - par exemple.

https://github.com/ProductiveRage/SqlProxyAndReplay/blob/master/Tests/StaysOpenSqliteConnection.cs

Questions connexes