单元测试 - 对SqlDataReader进行桩测试

16
我们有一个n层web应用程序,从SQL Server中获取数据。我们的数据访问逻辑返回一个SqlDataReader,它的数据然后用于创建我们的业务对象(也称为数据传输对象)。
我们希望构建单元测试来检查我们的代码解释SqlDataReader对象返回的数据以构建我们的业务对象。
因此,在单元测试期间构建替换SqlDataReader对象的存根似乎是必要的。正如可能相当典型的那样,我们的SqlDataReader对象通常返回多个记录集,每个记录集都有多行。
1.这是一个明智的尝试吗? 2.我们应该如何构建这些存根对象?
非常感谢您提前的回复。
Griff
1个回答

31

自动化测试通常是一个明智的努力 :)

要能够测试这个功能的第一步是,让您的数据访问逻辑返回一个 IDataReader 而不是 SqlDataReader -- 由于 SqlDataReader 实现了 IDataReader,所以没有问题。

在您的单元测试中,您可以手动构建和填充 DataTable 对象,并调用 dataTable.CreateDataReader() 来获取一个 IDataReader,然后将其传递给测试对象。

编辑

为了为您的测试提供一组示例数据,我建议为每个使用的数据表使用一个 ObjectMother,将创建数据表的过程放在一个专门的地方。然后,您可以在每个 ObjectMethod 类上放置方法,以强类型方式更新某些数据。例如:

public class PersonalDetailsBuilder
{
    private DataTable _dataTable;

    public PersonalDetailsBuilder CreateNewTable()
    {
        this._dataTable = new DataTable("CustomerPersonalDetails")
        {
            Columns = 
            {
                new DataColumn("CustomerId", typeof(int)),
                new DataColumn("CustomerName", typeof(string))
            }
        };

        return this;
    }

    public PersonalDetailsBuilder AddStandardData(int numberOfRows = 3)
    {
        foreach (int i in Enumerable.Range(1, numberOfRows + 1))
        {
            this.AddRow(i, "Customer " + i);
        }

        return this;
    }

    public PersonalDetailsBuilder AddRow(int customerId, string customerName)
    {
        this._dataTable.Rows.Add(customerId, customerName);

        return this;
    }

    public IDataReader ToDataReader()
    {
        return this._dataTable.CreateDataReader();
    }
}

你可以像这样使用它来获取数据读取器:

IDataReader customerDetailsReader = new PersonalDetailsBuilder()
    .CreateNewTable()
    .AddStandardData()
    .AddRow(17, "Customer 17")
    .ToDataReader();

想象一下,我们的IDataReader对象之一返回有关客户的详细信息:rs1 = 个人详细信息; rs2 = 权限; rs3-xxx等。大多数测试将使用此作为默认数据集。一些测试可能希望使用这些值中的大部分,但覆盖数据表中的某些属性。那有多容易?几乎像继承... - DrGriff
我不确定我理解了 - 你是指一个数据读取器用于多个结果集,还是一组数据读取器?无论如何,我已经更新了我的答案。 - Steve Wilkes
@DrGriff,你可能想要包含一个重载的AddStandardData方法,它只有一个类型为Action<DataRowCollection>的参数;在你的重载方法内部,你将调用原始的AddStandardData方法,然后执行该操作,传递this._DataTable.Rows属性。然后你可以在操作中操纵数据表中行的内容。 - David Keaveny

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