Как абстрагировать Linq2SQL для тестируемости

Я работаю над проектом, который использует Linq2SQL для доступа к данным. Проект состоит из приложения ASP.NET MVC и 8 библиотек классов. Большинство библиотек классов имеют свои собственные классы данных L2S.

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

Как я могу реорганизовать использование L2S, чтобы я мог проверить действия контроллера?

Я ввел инъекцию зависимостей в приложение, чтобы отделить некоторые другие сервисы, но я не хочу, чтобы DataContext был свойством зависимостей контроллеров, потому что я хочу контролировать создание экземпляров DataContexts и их DataLoadOptions.

Одна вещь, которую я попробовал, состояла в том, чтобы воспользоваться преимуществами частичных классов, которые генерирует L2S, и добавил интерфейс к DataContexts, но я обнаружил, что абстракция направлена ​​вверх, в приложение, а не в библиотеки классов. Это не было похоже на правильный способ делать вещи, и это было бы трудно поддерживать. Кто-нибудь имел какой-либо конкретный успех или неудачу с этим методом?

2 ответа

Решение

Я использую шаблон репозитория, чтобы скрыть DataContext внутри. Репозитории - это абстракции, поэтому они действительно хороши с принципом Dependency Injection.

Например, вы определяете некоторый репозиторий.

public interface IUserRepository
{
    User Get(int id);
    User Save(User user);
    void Delete(User user);
}

Реализация что-то вроде

public class UserRepository : IUserRepository
{
    private MyDataContext _context;

    UserRepository() 
    {
        _context = new MyDataContext();
    }

   // ...

}

Теперь контроллер зависит только от интерфейса.

public UserController : Controller
{
    UserController(IUserRepository userRepository) { }
}

Таким образом, это отлично проверяется, так как вы можете издеваться IUserRepository в ваших тестах.

Хотя эта статья относится к тестируемости использования структуры сущностей, здесь может применяться концепция высокого уровня.

Суть примеров изложена с использованием шаблона "Единица работы" с шаблоном "Репозиторий". Единица работы - это абстракция вокруг контекста данных, представляющая рабочий набор для конкретного контроллера или набор аналогичных контроллеров. Вы можете включить несколько хранилищ в устройство, и так как хранилища основаны на IEnumerable или же IQueryable Вы все еще можете воспользоваться преимуществами функциональности LINQ.

Варианты тестируемости включают макетирование модуля и репозиториев или создание представлений в памяти для целей тестирования.

Другие вопросы по тегам