Я реализовал модульное тестирование в соответствии с этой статьей с поддельным контекстом объекта и 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/
Но это будет означать, что мой реальный репозиторий не тестируется и, похоже, просто обходит проблему.
Может ли кто-нибудь предложить какие-либо рекомендации?
Ответ 1 · рейтинг 11 · Mark Seemann
Насколько я могу судить из вопроса, вы пытаетесь проверить слишком много одновременно. Помните о принципе единой ответственности.
При модульном тестировании мы используем абстрактные репозитории, чтобы абстрагировать код доступа к данным от остального приложения. С этой точки зрения мы тестируем только потребителей репозиториев, а не какой-либо конкретный репозиторий. Такие потребители должны заботиться только о репозиториях, а вовсе не о каком-либо "контексте объекта" - это будет дырявая абстракция.
Представьте, что вас неожиданно попросили связать ваших потребителей репозитория с совершенно другим уровнем данных (например, с сервисом на основе REST). В таких случаях даже контекст абстрактного объекта не имеет смысла. Возможно, вы никогда не ожидаете, что это произойдет, но даже в этом случае сам по себе мысленный эксперимент является довольно хорошим индикатором дырявой абстракции.
Контекст объекта - это деталь реализации вашей конкретной реализации репозитория, которая использует EF. Другие реализации могут вообще не нуждаться в объектном контексте.
Тем не менее, вы все равно можете протестировать саму реализацию EF. Это может иметь большой смысл, но это другой набор модульных тестов с совершенно другой целью. Вместо того, чтобы тестировать потребителей ваших абстрактных репозиториев, вы теперь тестируете конкретную реализацию репозитория. В этом случае нет необходимости проходить через интерфейсы - здесь вы можете напрямую общаться с конкретными типами.
Ответ 2 · Marcus
Можно ли протестировать фактические репозитории с базой данных в памяти, такой как SQLite? Существует поставщик SQLite для Entity Framework.
Похоже, что раздел SSDL в файле edmx связан с провайдером. Если вы создаете модель из базы данных Sql-сервера, будет установлен provider="System.Data.SqlClient". Это также будет установлено, если вы создаете базу данных sql-сервера из модели объекта.
Чего я действительно хотел бы, так это заставить мой производственный код использовать провайдера System.Data.SqlClient, а мои модульные тесты использовать провайдера System.Data.SqLite.