Как абстрагировать 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.
Варианты тестируемости включают макетирование модуля и репозиториев или создание представлений в памяти для целей тестирования.