Модульное тестирование с помощью платформы Entity Framework

Я хочу проверить свои объекты, которые создаются с использованием Entity Framework. Меня беспокоит, что использование Entity Framework означает непосредственную работу с источником данных. Итак, любые идеи о том, как модульное тестирование компонентов на основе Entity Framework?

Ответ 2

По-видимому, это очень сложно. Красноречиво поставил Эрик здесь - TDD и ADO.NET Entity Framework

Ответ 3

Дешевый подход заключается в том, чтобы создать файл базы данных с той же структурой, что и ваша реальная база данных, и установить строку подключения в конфигурации 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=&quot;Data Source=localhost\sqlexpress;Initial Catalog=Drinks2;Integrated Security=True;MultipleActiveResultSets=True;Application Name=EntityFramework&quot;" 
     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=&quot;Data Source=.\SQLEXPRESS;attachdbfilename=|DataDirectory|\Inventory.mdf;Integrated Security=True;user instance=True;MultipleActiveResultSets=True;Application Name=EntityFramework&quot;" 
     providerName="System.Data.EntityClient" />

Ответ 4

Вы захотите использовать Mocking Framework для извлечения ложных значений, а не для получения реальных данных. Вот список нескольких смехотворных фреймворков и ссылок на некоторые скринкасты, которые помогут вам начать:

Вот несколько скринкастов о том, как начать:

Ответ 6

В связи с тем, что версия 1 Entity Framework нарушает несколько основных принципов разработки программного обеспечения, на самом деле нет никакого способа применить TDD при ее использовании в вашем приложении. Мои исследования указывают на NHibernate, если вы ищете немедленное решение. Он был разработан с учетом модульных испытаний.

Однако, если вы можете ждать, похоже, есть надежда на следующий выпуск Entity Framework: Прохождение разработки с использованием платформы Entity Framework 4.0

Ответ 7

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

http://devblog.petrellyn.com/

Свяжитесь со мной, если вы хотите получить более подробную информацию.

Ответ 8

Я согласен, насмешливая структура - это то, что вам нужно. Вы создаете "издевавшиеся" объекты, которые не извлекаются из вашего источника данных, и вы проверяете данные в этом объекте. Я лично работал с Moq, и мне это нравится - есть также Rhinomocks и другие.

Ответ 9

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

Сначала используйте интерфейс репозитория, например:

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, реализованные ограничения могут быть нарушены, и некоторые проблемы с контекстом и базой данных, выходящие из синхронизации, могут возникнуть. Таким образом, в то время как тесты завершения интеграции все еще необходимы, можно поймать то, что является ИМО наиболее распространенной проблемой, возникающей во время выполнения в простых модульных тестах.

Ответ 10

Пример BookLibrary приложения Проект WPF Application Framework (WAF) показывает, как приложение на основе Entity Framework может быть проверено модулем.

Ответ 11

Здесь агрегация единицы рабочего шаблона + создание базы данных + t4 генерации кода для автоматической генерации поддельного EF dbContext.

http://mockingcompetence.wordpress.com/2013/05/20/fakingefdatacontext/

есть некоторые проблемы (недопустимые запросы linq для EF и отсутствие принудительного исполнения FK) с точным воспроизведением реального соединения EF db в настоящее время.

Однако наличие контекста в памяти для быстрого запуска модульных тестов почти необходимо для того, чтобы иметь возможность делать TDD или любой другой подход к централизованному тестированию.

Я буду размещать обновления для ссылки выше, поскольку я выясняю больше проблем.

Ответ 12

Вы можете использовать базу данных в памяти для тестирования модели Entity Framework. Посмотрите здесь для более подробной информации

Ответ 13

Как насчет использования насмешливой структуры? Мне кажется, что насмешливая структура может помочь вам изолировать вашу бизнес-логику от базы данных.