Модульное тестирование с помощью Entity Framework
Я хочу проверить мои сущности, которые построены с использованием Entity Framework. Меня беспокоит то, что использование Entity Framework означает прямую работу с источником данных. Итак, есть идеи, как модульное тестирование компонентов на основе Entity Framework?
13 ответов:
для Enity Framework 4 это выглядит многообещающе:тестируемость и Entity Framework 4.0
видимо это очень тяжело. Красноречиво поставленный Эриком здесь -TDD и ADO.NET Entity Framework
дешевый подход состоит в том, чтобы настроить файл базы данных с той же структурой, что и ваша реальная база данных, и установить строку подключения в конфигурации модульного теста, чтобы указать на это. База данных не должна иметь все таблицы, которые есть в реальной; только те, которые нужны для модульного теста.
недостатком является то, что вам нужно управлять состоянием базы данных, чтобы модульные тесты не влияли друг на друга или на себя во время и между запусками.
Я знаю этот подход работает, когда как реальные, так и модульные тестовые базы данных используют SQL Express, но я не знаю о стаббинге в базе данных SqlExpress для полной базы данных 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" />
вы собираетесь использовать насмешливую структуру для извлечения фиктивных значений, а не ударять по реальным данным. Вот список нескольких таких платформ и ссылки на некоторые видеоролики, чтобы помочь вам начать работу:
вот некоторые скринкасты о том, как начать:
Я хотел бы поделиться еще одним вкладом в это. Я также смог протестировать компоненты и приложения на основе Entity Framework с помощью изолятора TypeMock. Однако он является коммерческим.
взгляните на этот пост: представляем модульное тестирование 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, который, безусловно, где мы сталкиваемся с наибольшими проблемами.
его не идеально с любой натяжкой воображения, триггеры, очевидно, не будут запускаться, БД реализованные ограничения могут быть нарушены, и некоторые проблемы с контекстом и базой данных, выходящей из синхронизации, могут возникнуть. Так хотя сквозные интеграционные тесты все еще необходимы, можно поймать то, что является IMO наиболее распространенной проблемой, возникающей во время выполнения в простых модульных тестах.
The BookLibrary пример применения WPF Application Framework (WAF) проект показывает, как можно модульно протестировать приложение на основе Entity Framework.
вот агрегация единицы работы pattern + in-memory database + T4 Code generation для автоматического создания поддельного EF dbContext.
http://mockingcompetence.wordpress.com/2013/05/20/fakingefdatacontext/
есть некоторые проблемы (недопустимые запросы linq to EF и отсутствие принудительного применения FK) с точной репликацией реального соединения EF db в это время.
однако наличие контекста в памяти для быстрого запуска модульных тестов почти важно уметь делать TDD или любой другой вид модульного тестирования ориентированный подход.
Я буду публиковать обновления по приведенной выше ссылке, поскольку я выясняю больше проблем.
вы можете использовать базу данных в памяти для тестирования модели Entity Framework. Смотри здесь для более подробной информации