Модульное тестирование с Entity Framework - PullRequest
70 голосов
/ 28 ноября 2008

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

Ответы [ 13 ]

51 голосов
/ 09 июня 2010

Для Enity Framework 4 это выглядит многообещающим: Тестируемость и Entity Framework 4.0

7 голосов
/ 29 ноября 2008

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

6 голосов
/ 22 октября 2011

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

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

Я знаю, что этот подход работает, когда БД как реального, так и модульного тестирования используют 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" />
4 голосов
/ 26 января 2010

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

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

4 голосов
/ 15 сентября 2009

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

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

4 голосов
/ 01 декабря 2008

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

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

3 голосов
/ 19 мая 2009

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

http://devblog.petrellyn.com/

Свяжитесь со мной, если хотите узнать больше.

2 голосов
/ 07 июня 2013

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

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

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 является наиболее распространенной проблемой, возникающей во время выполнения, в простых модульных тестах.

2 голосов
/ 01 декабря 2008

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

0 голосов
/ 15 октября 2013

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...