У меня есть прекрасно отделенное приложение и приложение с зависимостями, которое использует Entity Framework 4.1 CodeFirst для предоставления IQueryable через шаблон репозитория. При тестировании клиентов репозитория достаточно легко смоделировать базовое хранилище данных, однако определенный класс ошибок не обнаруживается:
Клиенты репозитория могут свободно размещать свои собственные предикаты LINQ, объединения и т. Д. Поверх того, что возвращает репозиторий:
{
_myRepository.FindAll().Where( x => x.Id == 3 && SomeMethod(x.Name) == "Hello" );
}
Этот тип запроса будет успешным в модульном тесте, который создает макет _myRepository, потому что mock возвращает коллекцию сущностей в памяти, а LINQ-to-Objects с радостью вызывает метод SomeMethod. Это не сработает с реальным хранилищем данных, потому что SomeMethod не переводится в SQL в LINQ-to-Entities.
Я пытаюсь найти способ, с помощью которого я мог бы и издеваться над набором данных, и заставить настоящий поставщик запросов EF генерировать (но не выполнять) SQL. Зачем? Потому что тесты должны быть быстрыми, и я не хочу, чтобы они били по реальной базе данных, если это вообще возможно. Генерация SQL избавит от проблем перевода, подобных этой.
До сих пор я не смог понять, как это сделать, потому что в моих модульных тестах я в конечном счете не контролирую, когда запрос материализуется. Я думаю, что мне нужно либо предоставить свою собственную версию IQueryable и различные методы расширения LINQ Queryable, либо попробовать подключиться через механизм провайдера (используя пример, полученный пару лет назад для провайдеров Caching / Tracing). это похоже на большую работу. Есть идеи, как этого добиться?