Репликация поведения LINQ to Entities в модульных тестах, использующих LINQ to Object - PullRequest
8 голосов
/ 21 июня 2011

В моем решении у меня есть модульные тесты, которые не зависят от базы данных, а скорее имитируют и интеграционные тесты, которые имеют внешние зависимости, такие как база данных.

Когда я выполняю модульные тесты с макетами, используется LINQ to Object. При выполнении интеграционных тестов или реальной программы используется LINQ to Entities, и она более строгая, чем LINQ to Object.

Есть ли способ реплицировать более строгое поведение LINQ To Object в моих модульных тестах?

Ответы [ 3 ]

6 голосов
/ 22 июня 2011

Как только логика, протестированная вашим модулем, работает с IQueryable, предоставленным EF, вы просто не можете проверить его с помощью модульных тестов, имитируя EF. Это всегда приведет к переключению с linq-to-objects на linq-to-objects. В случае чего-то упрощенного, правильным способом справиться с этим в модульном тесте является написание фейка вместо макета. Подделка будет имитировать поведение зависимости. В этом случае подделка означает написание EF-провайдера, работающего над сбором в памяти, точно так же, как реальный провайдер работает с базой данных. Написание такого провайдера, наверное, сам проект.

Из-за этого, как только ваша логика содержит запросы linq-to-entity, вы всегда должны тестировать ее с помощью интеграционных тестов или рефакторинга кода, чтобы сам запрос выполнялся отдельным методом (тестируется интеграционными тестами), а прежняя логика теперь зависела от класс, содержащий метод вместо этого в самом EF - это приводит к шаблону репозитория, где IQueryalbe не предоставляется, но репозиторий предоставляет метод для каждого необходимого запроса, работающего на некотором объекте. Мне лично не нравятся такие репозитории. Вот недавнее обсуждение о различных реализациях репозитория.

Если вы решите использовать интеграционные тесты, меняющие базу данных в оперативную память, то это возможно с помощью EFv4.1 и кода вначале, когда вы просто меняете строку подключения на SQL Compact 4, и она будет работать (если вы не используете какой-то специальный прямой SQL вызывает или требует некоторых специальных типов SQL в отображении). В случае EF с файлом EDMX это не будет работать, поскольку файл EDMX тесно связан с точной версией базы данных. Использование специального EDMX только для модульного тестирования не вариант, потому что вы снова протестируете другой код.

Вот набор связанных вопросов обсуждение проблем с модульным тестированием кода EF и репозиториев.

0 голосов
/ 21 июня 2011

Если вы хотите, чтобы ваши модульные тесты для слоя, который взаимодействует с базой данных, имели реальное значение и все поведения, как в рабочем коде, вам нужно поговорить с базой данных. Это может рассматриваться как нарушение правила отсутствия зависимостей в модульном тесте, но нет другого способа заставить LINQ to Entities выполнять свою работу, кроме как позволить ему общаться с real базой данных. Это может быть (и, вероятно, должно быть) база данных в памяти - см., Например, , как Айенде делает это .

0 голосов
/ 21 июня 2011

Вы можете использовать шаблон репозитория для определения интерфейса IRepository, в своем реальном коде вы можете реализовать его с помощью Entity Framework, а в своем модульном тесте вы можете использовать mock framework для возврата объектов для тестирования.

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