7

我正在尝试对一些 .NET 类进行单元测试(出于良好的设计原因),这些类需要 DbConnections 来完成它们的工作。对于这些测试,我在内存中有某些数据可以作为这些类的输入。

内存中的数据可以很容易地表示为 DataTable(或包含该 DataTable 的 DataSet),但如果另一个类更合适,我可以使用它。

如果我能够以某种方式神奇地获得一个表示与内存中数据的连接的 DbConnection,那么我可以构造我的对象,让它们对内存中的数据执行查询,并确保它们的输出符合预期。 有什么方法可以让 DbConnection 连接到内存数据? 我没有安装任何额外的第三方软件来实现这一点的自由,理想情况下,我不想在测试期间触摸磁盘。

4

3 回答 3

7

您可以使用 IDbConnection 并模拟它,而不是使用 DbConnection 吗?我们做类似的事情,给 mock 传递一个 DataSet。DataSet.CreateDataReader 返回一个继承自 DbDataReader 的 DataTableReader。

我们已经将 DbConnection 包装在我们自己的类似 IDbConnection 的接口中,我们向其中添加了一个 ExecuteReader() 方法,该方法返回一个实现与 DbDataReader 相同接口的类。在我们的模拟中,ExecuteReader 只返回 DataSet.CreateDataReader 提供的内容。

听起来有点迂回,但构建一个可能包含许多结果集的 DataSet 非常方便。我们以它们代表结果的存储过程命名 DataTables,并且我们的 IDbConnection 模拟根据客户端调用的过程获取正确的数据表。DataTable 还实现了 CreateDataReader,所以我们可以开始了。

于 2009-03-26T11:58:58.733 回答
4

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

于 2016-07-28T07:52:22.243 回答
1

类型模拟?(不过,您需要“安装”它)。

假设 Data* 可以为您提供适当的测试钩子,请小心——这通常是最坏的情况。但是你说好的设计原因,所以我确信这一切都包括在内:D

于 2009-03-26T11:44:01.000 回答