Ответ 1
Для Enity Framework 4 это выглядит многообещающим: Testability и Entity Framework 4.0
Я хочу проверить свои объекты, которые создаются с использованием Entity Framework. Меня беспокоит, что использование Entity Framework означает непосредственную работу с источником данных. Итак, любые идеи о том, как модульное тестирование компонентов на основе Entity Framework?
Для Enity Framework 4 это выглядит многообещающим: Testability и Entity Framework 4.0
По-видимому, это очень сложно. Красноречиво поставил Эрик здесь - TDD и ADO.NET Entity Framework
Дешевый подход заключается в том, чтобы создать файл базы данных с той же структурой, что и ваша реальная база данных, и установить строку подключения в конфигурации unit test, чтобы указать на это. База данных не обязательно должна иметь все таблицы, которые есть у реального; только те, которые нужны unit test.
Недостатком является то, что вам нужно управлять состоянием базы данных, чтобы модульные тесты не влияли друг на друга или на себя во время и между прогонами.
Я знаю, что этот подход работает, когда как реальные, так и отдельные тестовые БД используют SQL Express, но я не знаю о stubbing в SqlExpress DB для полной базы данных SQL.
Я понимаю, что это технически интеграционное тестирование, но оно может быть дешевле, чем рефакторинг вашего кода или изучение насмешливой структуры.
Пример реальной строки подключения:
<add name="DrinksEntities"
connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlClient
;provider connection string="Data Source=localhost\sqlexpress;Initial Catalog=Drinks2;Integrated Security=True;MultipleActiveResultSets=True;Application Name=EntityFramework""
providerName="System.Data.EntityClient" />
Пример тестирования строки подключения:
<add name="DrinksEntities"
connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlClient
;provider connection string="Data Source=.\SQLEXPRESS;attachdbfilename=|DataDirectory|\Inventory.mdf;Integrated Security=True;user instance=True;MultipleActiveResultSets=True;Application Name=EntityFramework""
providerName="System.Data.EntityClient" />
Вы захотите использовать Mocking Framework для извлечения ложных значений, а не для получения реальных данных. Вот список нескольких смехотворных фреймворков и ссылок на некоторые скринкасты, которые помогут вам начать:
Вот несколько скринкастов о том, как начать:
Я хотел бы поделиться другим материалом. Я смог протестировать компоненты и приложение на базе платформы Entity Framework с использованием TypeMock Isolator. Однако это коммерчески.
Взгляните на этот пост: Знакомство с модулем Unit Entity Framework с помощью изолятора TypeMock
В связи с тем, что версия 1 Entity Framework нарушает несколько основных принципов разработки программного обеспечения, на самом деле нет никакого способа применить TDD при ее использовании в вашем приложении. Мои исследования указывают на NHibernate, если вы ищете немедленное решение. Он был разработан с учетом модульных испытаний.
Однако, если вы можете ждать, похоже, есть надежда на следующий выпуск Entity Framework: Прохождение разработки с использованием платформы Entity Framework 4.0
Хотя примеры могут быть очень упрощенными, я попытался обсудить возможное решение этой самой проблемы. Это включает разделение проблем и нашего дорогого друга Инъекции зависимостей.
Свяжитесь со мной, если вы хотите получить более подробную информацию.
Я согласен, насмешливая структура - это то, что вам нужно. Вы создаете "издевавшиеся" объекты, которые не извлекаются из вашего источника данных, и вы проверяете данные в этом объекте. Я лично работал с Moq, и мне это нравится - есть также Rhinomocks и другие.
После многих разочарований в этом я, наконец, получил решение, для которого я доволен, по крайней мере, частью проблемы.
Сначала используйте интерфейс репозитория, например:
public interface IRepository
{
IQueryable<T> GetObjectSet<T>();
}
который мы можем использовать для возврата либо в коллекцию памяти, либо в реальную коллекцию с поддержкой БД. Затем инкапсулируйте свои запросы в объект запроса с помощью интерфейса, который выглядит примерно так.
public interface IQuery<T>
{
IQueryable<T> DoQuery(IQueryable<T> collection);
}
Разделите свои модульные тесты на 2 группы. Первая группа проверит, что ваши запросы действительны. сделайте это так:
[TestMethod]
public void TestQueryFoo()
{
using(var repo = new SqlRepository("bogus connection string"))
{
var query = new FooQuery(); // implements IQuery<Foo>
var result = query.DoQuery(repo.GetObjectSet<Foo>()); // as long as we don't enumerate the IQueryable EF won't notice that the connection string is bogus
var sqlString = ((System.Data.Objects.ObjectQuery)query).ToTraceString(); // This will throw if the query can't be compiled to SQL
}
}
Второй набор модульных тестов затем может свободно протестировать вашу бизнес-логику, не беспокоясь о шаге компиляции SQL, который, безусловно, встречается в большинстве проблем.
Его не идеально по какой-либо части воображения, триггеры, очевидно, не будут запущены, DB, реализованные ограничения могут быть нарушены, и некоторые проблемы с контекстом и базой данных, выходящие из синхронизации, могут возникнуть. Таким образом, в то время как тесты завершения интеграции все еще необходимы, можно поймать то, что является ИМО наиболее распространенной проблемой, возникающей во время выполнения в простых модульных тестах.
Пример BookLibrary приложения Проект WPF Application Framework (WAF) показывает, как приложение на основе Entity Framework может быть проверено модулем.
Здесь агрегация единицы рабочего шаблона + создание базы данных + t4 генерации кода для автоматической генерации поддельного EF dbContext.
http://mockingcompetence.wordpress.com/2013/05/20/fakingefdatacontext/
есть некоторые проблемы (недопустимые запросы linq для EF и отсутствие принудительного исполнения FK) с точным воспроизведением реального соединения EF db в настоящее время.
Однако наличие контекста в памяти для быстрого запуска модульных тестов почти необходимо для того, чтобы иметь возможность делать TDD или любой другой подход к централизованному тестированию.
Я буду размещать обновления для ссылки выше, поскольку я выясняю больше проблем.
Вы можете использовать базу данных в памяти для тестирования модели Entity Framework. Посмотрите здесь для более подробной информации
Как насчет использования насмешливой структуры? Мне кажется, что насмешливая структура может помочь вам изолировать вашу бизнес-логику от базы данных.