DbConnection without Db using in-memory DataSet (or similar) as source

落爺英雄遲暮 提交于 2019-11-29 04:26:07

Rather than consume a DbConnection can you consume IDbConnection and mock it? We do something similar, pass the mock a DataSet. DataSet.CreateDataReader returns a DataTableReader which inherits from DbDataReader.

We have wrapped DbConnection in our own IDbConnection-like interface to which we've added an ExecuteReader() method which returns a class that implements the same interfaces as DbDataReader. In our mock, ExecuteReader simply returns what DataSet.CreateDataReader serves up.

Sounds kind of roundabout, but it is very convenient to build up a DataSet with possibly many resultsets. We name the DataTables after the stored procs that they represent the results of, and our IDbConnection mock grabs the right Datatable based on the proc the client is calling. DataTable also implements CreateDataReader so we're good to go.

An approach that I've used is to create an in-memory Sqlite database. This may be done simply by pulling in the System.Data.SQLite.Core NuGet package to your unit test project, you don't need to install any software anywhere else.

Although it sounds like a really obvious idea, it wasn't until I was looking at the Dapper unit tests that I thought to use the technique myself! See the "GetSqliteConnection" method in

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

One thing to be aware of is that if you create an in-memory sqlite db and create and populate tables, you need to be careful not to close the connection before performing your test queries because opening a new in-memory connection will get you a connection to a new in-memory database, not the database that you just carefully prepared for your tests! For some of my tests, I use a custom IDbConnection implementation that keeps the connection open to avoid this pitfall - eg.

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

TypeMock? (You would need to 'install' it though).

Be careful assuming that Data* can give you proper hooks for testing - its pretty the worst case in general. But you say Good Design Reasons, so I'm sure that's all covered :D

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!