Модульное тестирование - заглушка SqlDataReader - PullRequest
13 голосов
/ 28 марта 2012

У нас есть n-уровневое веб-приложение, которое извлекает данные из SQL Server. Наша логика доступа к данным возвращает SqlDataReader, данные которого затем используются для создания наших бизнес-объектов (a.k.a. объекты передачи данных).

Мы хотим создать модульные тесты для проверки нашего кода, который интерпретирует данные, возвращаемые этими объектами SqlDataReader, для построения наших бизнес-объектов.

Поэтому представляется необходимым создать заглушки для замены объектов SqlDataReader во время модульного тестирования. Как это, вероятно, довольно типично, наши объекты SqlDataReader обычно возвращают несколько наборов записей, каждый с несколькими строками.

  1. Это разумное начинание?
  2. Как мы должны строить эти объекты-заглушки?

Большое спасибо заранее

Griff

1 Ответ

25 голосов
/ 28 марта 2012

Автоматическое тестирование - это всегда разумное занятие :) 1001 *

Ваш первый шаг к возможности проверить это состоит в том, чтобы ваша логика доступа к данным возвращала 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[]
            {
                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();
...