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


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

13 70

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=&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" />

вы собираетесь использовать насмешливую структуру для извлечения фиктивных значений, а не ударять по реальным данным. Вот список нескольких таких платформ и ссылки на некоторые видеоролики, чтобы помочь вам начать работу:

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

Я хотел бы поделиться еще одним вкладом в это. Я также смог протестировать компоненты и приложения на основе Entity Framework с помощью изолятора TypeMock. Однако он является коммерческим.

взгляните на этот пост: представляем модульное тестирование Entity Framework с изолятором TypeMock

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

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

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

http://devblog.petrellyn.com/

свяжитесь со мной, если вы хотите более детально.

Я согласен, насмешливая структура - это то, что вам нужно. Вы создаете "издевательские" объекты, которые не извлекаются из вашего источника данных, и вы тестируете данные в этом объекте. Я лично работал с 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. Смотри здесь для более подробной информации

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