在不使用数据库的情况下,如何使用内存中的DataSet(或类似物)作为数据源来创建DbConnection?

7

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

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

如果我能以某种神奇的方式获得代表连接到内存数据的DbConnection,那么我就可以构造我的对象,让它们执行其针对内存数据的查询,并确保它们的输出符合预期。是否有办法获取到连接到内存数据的DbConnection?我没有自由安装任何额外的第三方软件来实现这一点,并且最理想的情况是在测试期间不需要接触硬盘。

3个回答

7
与其使用DbConnection,你可以使用IDbConnection并进行模拟吗?我们做了类似的事情,将模拟传递给一个DataSet。DataSet.CreateDataReader返回一个继承自DbDataReader的DataTableReader。
我们已经在自己的IDbConnection-like接口中包装了DbConnection,并添加了一个ExecuteReader()方法,该方法返回一个实现与DbDataReader相同接口的类。在我们的模拟中,ExecuteReader只是返回DataSet.CreateDataReader提供的内容。
听起来有点绕,但是用于构建可能具有许多结果集的DataSet非常方便。我们根据它们表示结果的存储过程的名称命名DataTable,并且我们的IDbConnection模拟基于客户端调用的存储过程获取正确的Datatable。DataTable还实现了CreateDataReader,所以我们可以开始了。

4

我使用的一种方法是创建一个内存中的Sqlite数据库。这可以通过将System.Data.SQLite.Core NuGet包引入到您的单元测试项目中来简单实现,您不需要在任何其他地方安装任何软件。

虽然这听起来像一个非常明显的想法,但直到我看Dapper单元测试时,我才想到使用这种技术!请参见“GetSqliteConnection”方法。

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

需要注意的是,如果您创建了一个内存中的sqlite数据库并创建和填充表格,则在执行测试查询之前,需要小心不要关闭连接,因为打开新的内存连接将使您连接到一个新的内存数据库,而不是您为测试精心准备的数据库!对于我的一些测试,我使用自定义的IDbConnection实现来保持连接以避免这种陷阱 - 例如。

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


1

TypeMock?(不过你需要“安装”它)。

小心假设Data*可以为您提供适当的测试钩子-通常情况下这是最糟糕的情况。但是你说有良好的设计理由,所以我相信一切都已经覆盖了:D


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接