Если вы хотите использовать TDD (или любой другой подход к тестированию с высоким охватом тестирования) и EF вместе, вы должны написать интеграционные или сквозные тесты.Проблема здесь в том, что любой подход с макетом контекста или репозитория просто создает тест, который может проверить вашу логику верхнего уровня (которая использует эти макеты), но не ваше приложение.
Простой пример:
Давайтеопределить универсальный репозиторий:
public interface IGenericRepository<TEntity>
{
IQueryable<TEntity> GetQuery();
...
}
И давайте напишем некоторый бизнес-метод:
public IEnumerable<MyEntity> DoSomethingImportant()
{
var data = MyEntityRepo.GetQuery().Select((e, i) => e);
...
}
Теперь, если вы смоделируете репозиторий, вы будете использовать Linq-To-Objects и у вас будет зеленый тестно если вы запустите приложение с Linq-To-Entities, вы получите исключение, потому что перегрузка select с индексами не поддерживается в L2E.
Это был простой пример, но то же самое может случиться с использованием методов в запросах и других распространенныхошибки.Кроме того, это также влияет на такие методы, как Add, Update, Delete, обычно предоставляемые в хранилище.Если вы не пишете макет, который будет точно имитировать поведение контекста EF и ссылочную целостность, вы не будете тестировать свою реализацию.
Еще одна часть истории - проблемы с отложенной загрузкой, которые также трудно обнаружить при модульных тестах на mock.
Из-за этого вам также следует ввести интеграционные или сквозные тесты, которые будутработать с реальной базой данных, используя реальный контекст EF и L2E.Btw.Для правильного использования TDD требуется использование сквозных тестов.Для написания сквозных тестов в ASP.NET MVC вы можете WatiN и, возможно, также SpecFlow для BDD, но это действительно добавит много работы, но ваше приложение будет действительноиспытания.Если вы хотите узнать больше о TDD, я рекомендую эту книгу (единственный недостаток - примеры на Java).
Интеграционные тесты имеют смысл, если вы не используете универсальный репозиторий и выскрыть ваши запросы в каком-то классе, который не будет представлять IQueryable
, но будет возвращать непосредственно данные.
Пример:
public interface IMyEntityRepository
{
MyEntity GetById(int id);
MyEntity GetByName(string name);
}
Теперь вы можете просто написать интеграционный тест для проверки реализации этого репозитория, поскольку запросыскрыты в этом классе и не подвергаются воздействию верхних слоев.Но этот тип хранилища почему-то рассматривается как старая реализация, используемая с хранимыми процедурами.С этой реализацией вы потеряете много функций ORM, или вам придется проделать много дополнительной работы - например, добавить шаблон спецификации , чтобы иметь возможность определять запрос на верхнем уровне.
В ASP.NET MVC вы можете частично заменить сквозные тесты интеграционными тестами на уровне контроллера.
Редактировать на основе комментария:
Я не говорю, что вам нужны юнит-тесты, интеграционные тесты и сквозные тесты.Я говорю, что создание проверенных приложений требует гораздо больших усилий.Количество и типы необходимых тестов зависят от сложности вашего приложения, ожидаемого будущего приложения, ваших навыков и умений других членов команды.
Небольшие прямые проекты могут быть созданы вообще без тестов (хорошо, это не очень хорошая идея, но мы все сделали это, и в конце это сработало), но как только проект преодолеет некоторый порог, вы обнаружите, что введение новыхФункции или поддержка проекта очень сложны, потому что вы никогда не уверены, что он нарушает то, что уже сработало - это называется регрессией.Лучшая защита от регрессии - хороший набор автоматизированных тестов.
- Модульные тесты помогут вам проверить метод.Такие тесты в идеале должны охватывать все пути выполнения в методе.Эти тесты должны быть очень короткими и простыми в написании - для сложной части можно настроить зависимости (mocks, faktes, stubs).
- Интеграционные тесты помогают тестировать функциональность на нескольких уровнях и обычно на нескольких процессах (приложение, база данных).Вам не нужно иметь их для всего, это больше опыта, чтобы выбрать, где они полезны.
- Сквозные тесты - это что-то вроде проверки варианта использования / пользовательской истории / функции.Они должны охватывать весь поток требований.
Нет необходимости тестировать выборку несколько раз - если вы знаете, что функция тестируется в сквозном тесте, вам не нужно писать интеграционный тест для одного и того же кода.Также, если вы знаете, что у метода есть только один путь выполнения, который охватывается интеграционным тестом, вам не нужно писать для него модульный тест.Это работает намного лучше с подходом TDD, когда вы начинаете с большого теста (сквозного или интеграционного) и углубляетесь в модульные тесты.
В зависимости от вашего подхода к разработке вам не нужно начинать с несколькихтипы тестов с самого начала, но вы можете представить их позже, поскольку ваше приложение станет более сложным.Исключением является TDD / BDD, где вы должны начать использовать как минимум сквозные и модульные тесты, прежде чем писать хотя бы одну строку другого кода.
Таким образом, вы задаете неправильный вопрос.Вопрос не в том, что проще?Вопрос в том, что поможет вам в конце и какая сложность подходит для вашего приложения?Если вы хотите, чтобы приложение и бизнес-логика легко тестировались модульно, вам следует связать код EF с некоторыми другими классами, которые можно смоделировать.Но в то же время вы должны ввести другие типы тестов, чтобы убедиться, что код EF работает.
Я не могу сказать вам, какой подход подойдет вашей среде / проекту / команде / и т. Д. Но я могу объяснить пример изМой прошлый проект:
Я работал над проектом около 5-6 месяцев с двумя коллегами.Проект был основан на ASP.NET MVC 2 + jQuery + EFv4 и разрабатывался поэтапно и итеративно.У него было много сложной бизнес-логики и много сложных запросов к базе данных.Мы начали с универсальных репозиториев и высокого покрытия кода с модульными тестами + интеграционными тестами для проверки соответствия (простые тесты для вставки, удаления, обновления и выбора объекта).Через несколько месяцев мы обнаружили, что наш подход не работает.У нас было более 1.200 модульных тестов, охват кода около 60% (что не очень хорошо) и множество проблем регрессии.Изменение чего-либо в модели EF может привести к неожиданным проблемам в деталях, которые не затрагивались в течение нескольких недель.Мы обнаружили, что нам не хватает интеграционных тестов или сквозных тестов для логики нашего приложения.Тот же вывод был сделан в параллельной команде, работавшей над другим проектом, и использование интеграционных тестов рассматривалось как рекомендация для новых проектов.