Модульное тестирование Entity Framework 4.0

Я реализовал модульное тестирование в соответствии с этой статьей с поддельным контекстом объекта и IObjectSet с POCO в EF4.

http://blogs.msdn.com/adonet/archive/2009/12/17/test-driven-development-walkthrough-with-the-entity-framework-4-0.aspx

Но я не уверен, как реализовать пару методов в контексте моего поддельного объекта для тестирования. У меня есть методы CreateQuery и ExecuteFunction в моем интерфейсе контекста объекта, поэтому я могу выполнять ESQL и хранимые процедуры, но я не могу (легко) реализовать их в моем фальшивом контексте объекта.

Альтернативой может быть использование тестового двойника моего репозитория вместо двойника моего контекста объекта, как предлагается здесь:

http://social.msdn.microsoft.com/Forums/en-US/adonetefx/thread/c4921443-e8a3-4414-92dd-eba1480a07ad/

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

Может ли кто-нибудь предложить какие-либо рекомендации?


person Steve Ward    schedule 29.12.2009    source источник


Ответы (2)


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

При модульном тестировании мы используем абстрактные репозитории, чтобы абстрагировать код доступа к данным от остального приложения. С этой точки зрения мы тестируем только потребителей репозиториев, а не какой-либо конкретный репозиторий. Такие потребители должны заботиться только о репозиториях, а вовсе не о каком-либо «контексте объекта» — это будет дырявая абстракция.

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

Контекст объекта — это деталь реализации вашей конкретной реализации репозитория, которая использует EF. Другие реализации могут вообще не нуждаться в объектном контексте.

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

person Mark Seemann    schedule 29.12.2009
comment
действительно отличный ответ. Знаете ли вы какие-либо эффективные способы тестирования репозиториев? В идеале я бы использовал для этого базу данных в памяти, за исключением того, что EF4 не работает ни с одной из них без значительных изменений. - person Steven Evers; 09.12.2010
comment
Я не знал бы о EF4 (я более или менее отказался от EF), но с предыдущими версиями не было швов, которые позволяли бы в памяти DB каким-либо простым способом. Теоретически, поскольку EF основан на расширяемой модели провайдера, вы можете использовать базу данных в памяти в качестве базовой БД, если сможете найти провайдера, но я не знаю ни одного. Опять же, я долго не искал... - person Mark Seemann; 09.12.2010

Можно ли протестировать фактические репозитории с базой данных в памяти, такой как SQLite? Существует поставщик SQLite для Entity Framework.

Похоже, что раздел SSDL в файле edmx связан с провайдером. Если вы создаете модель из базы данных Sql-сервера, будет установлен provider="System.Data.SqlClient". Это также будет установлено, если вы создаете базу данных sql-сервера из модели объекта.

Чего я действительно хотел бы, так это заставить мой производственный код использовать провайдера System.Data.SqlClient, а мои модульные тесты использовать провайдера System.Data.SqLite.

person Marcus    schedule 25.05.2010
comment
Переключить БД с EF не очень сложно, если для вашей БД есть поставщик, поддерживающий EF. Вот хороший пост о том, как это сделать: mosesofegypt.net/ пост/ - person Odrade; 14.12.2010