Метод модульного тестирования с ложным DAL, но базовый метод вызывает другой (настоящий) DAL - PullRequest
0 голосов
/ 21 июля 2010

Я пытаюсь реализовать модульные тесты в моем текущем проекте.После этого я начну разработку с использованием TDD далее в этом проекте.Вчера я начал делать некоторые тесты, и это было не так просто, как кажется в теории / книгах.

В настоящий момент я борюсь с определенным сценарием, с которым я знаю, что кто-то еще должен был работать вПрошлое также.

Некоторая справочная информация.У меня есть метод с именем Add() в классе AddProduct.Когда новый объект передается методу Add, сначала должен быть создан новый элемент, поэтому сначала мне нужно вызвать метод Add() класса AddItem.Весь этот код существует на бизнес-уровне.Конечно, реальное добавление происходит в DAL, который вызывается из моих классов AddProduct и AddItem.

Чтобы понять, вот что у меня есть:

public class AddProduct : Product<IDataAccessAdd<Entities.Product>>, IBusinessAdd<Entities.Product>
{
    private readonly Business.IBusinessAdd<Entities.Item> _addItem;
    public AddProduct() : base(new DataAccess.AddProduct())
    {
        _addItem = new AddItem();
    }
        public AddProduct(DataAccess.IDataAccessAdd<Entities.Product> dal, Business.IBusinessAdd<Entities.Item> itemBl) : base(dal)
    {
        _addItem = itemBl;
    }

    private Entities.Product _newProduct;
    public bool Add(ref Product product, string user)
    {
        bool isAdded = false;
        _newProduct = product;
        if(AddNewItem(user))
        {
            isAdded = Dal.Add(product);
        }
        return isAdded;
    }

    private bool AddNewItem(string user)
    {
        var newItem = new Item();
        bool isAdded = _addItem.Add(ref newItem, user);
        _newProduct.Item = newItem;
        return isAdded;
    }
}

Как видите, я вызываю AddNewItem из метода Add.

Проблема в этом примере - конструктор.Я хотел бы иметь конструктор с 0 или 1 параметром, например так:

public AddProduct() : base(new DataAccess.AddProduct())
{
}
public AddProduct(DataAccess.IDataAccessAdd<Entities.Product> dal) : base(dal)
{
}

и метод AddNewItem примерно так (или что-то похожее):

private bool AddNewItem(string user)
{
    var newItem = new Item();
    var addItem = new Business.AddItem();
    bool isAdded = addItem.Add(ref newItem, user);
    _newProduct.Item = newItem;
    return isAdded;
}

Но при выполнениикод, выполняемый в методе AddNewItem, использует «настоящий» DAL, и я не хочу этого в модульном тесте.Я решил эту проблему, добавив новый параметр в конструктор, который также может создать фиктивный DAL для класса Business.Item.Тем не менее, я не думаю, что это путь.Теоретически, вы можете получить конструктор с 20 параметрами, которые используются для модульного тестирования.Не очень красивое зрелище.

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

Какие-либо другие предложения, которые я мог бы попробовать?

1 Ответ

3 голосов
/ 21 июля 2010

Здесь вы можете использовать два подхода.

  1. Настройка контейнера IOC специально для тестирования. В этом контейнере вы настроите службу dal в качестве тестовой или фиктивной службы DAL.

  2. Подключите свои занятия вручную. В этом случае вы явно вызываете конструктор AddProduct и передаете свой тестовый или фиктивный сервис DAL.

Основанием для этого является то, что внедрение зависимостей позволяет вам создать «песочницу» для изоляции и тестирования определенной части вашего кода. Опции выше создают эту песочницу.

...