单元测试-存根SqlDataReader

问题描述 投票:13回答:1

我们有一个n层Web应用程序,可从SQL Server中提取数据。我们的数据访问逻辑返回一个SqlDataReader,然后将其数据用于创建我们的业务对象(也称为数据传输对象)。

我们希望构建单元测试来检查我们的代码,这些代码解释了这些SqlDataReader对象返回的数据以构建我们的Business对象。

因此,似乎有必要在单元测试期间构建存根来替换SqlDataReader对象。大概是很典型的,我们的SqlDataReader对象通常返回多个记录集,每个记录集都有多行。

  1. 这是明智的努力吗?
  2. 我们应该如何构建这些存根对象?

非常感谢

Griff

unit-testing nunit sqldatareader stub stub-data-generation
1个回答
26
投票

自动测试基本上总是明智的选择:)

您要进行测试的第一步是让您的数据访问逻辑返回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();
© www.soinside.com 2019 - 2024. All rights reserved.