我正在尝试对几个.NET类进行单元测试(出于好的设计原因)需要DbConnections来完成他们的工作。对于这些测试,我在内存中有一些数据作为这些类的输入。
内存数据可以很容易地表示为DataTable(或包含该DataTable的DataSet),但如果另一个类更合适,我可以使用它。
如果我以某种方式神奇地能够获得表示内存数据连接的DbConnection,那么我可以构建我的对象,让它们对内存中的数据执行查询,并确保它们的输出符合预期。 有没有办法让DbConnection进入内存数据?我没有自由安装任何额外的第三方软件来实现这一点,理想情况下,我不想在测试期间触摸磁盘。
答案 0 :(得分:6)
您可以使用IDbConnection并模拟它,而不是使用DbConnection吗?我们做类似的事情,传递模拟一个DataSet。 DataSet.CreateDataReader返回一个继承自DbDataReader的DataTableReader。
我们已经将DbConnection包装在我们自己的类似IDbConnection的接口中,我们已经添加了一个ExecuteReader()方法,该方法返回一个实现与DbDataReader相同接口的类。在我们的模拟中,ExecuteReader只返回DataSet.CreateDataReader提供的内容。
听起来有点迂回,但是建立一个可能有很多结果集的DataSet非常方便。我们在存储的procs之后命名DataTables,它们代表结果,我们的IDbConnection mock根据客户端调用的proc获取正确的Datatable。 DataTable还实现了CreateDataReader,所以我们很高兴。
答案 1 :(得分:3)
我使用的方法是创建内存中的Sqlite数据库。这可以通过将System.Data.SQLite.Core NuGet包拉入您的单元测试项目来完成,您不需要在任何其他地方安装任何软件。
虽然听起来这是一个非常明显的想法,但直到我看到Dapper单元测试时我才想到自己使用这种技术!请参阅" GetSqliteConnection"
中的方法要注意的一件事是,如果您创建内存中的sqlite数据库并创建和填充表,则在执行测试查询之前需要注意不要关闭连接,因为打开新的内存中连接将让你连接到新的内存数据库,不你刚为测试准备好的数据库!对于我的一些测试,我使用自定义IDbConnection实现来保持连接打开以避免这种陷阱 - 例如。
https://github.com/ProductiveRage/SqlProxyAndReplay/blob/master/Tests/StaysOpenSqliteConnection.cs
答案 2 :(得分:0)
TypeMock? (你需要'安装'它。)
小心假设Data *可以为您提供适当的测试钩子 - 这通常是最糟糕的情况。但是你说好设计原因,所以我确信这些都包括在内:D