"К сожалению, вы делаете это неправильно, потому что эта статья неверна. Она делает вид, что FakeContext сделает ваш код тестируемым, но не будет"
Я создатель поста в блоге, на который вы ссылаетесь. Проблема, которую я вижу здесь, заключается в неправильном понимании основ модульного тестирования N-Layered. Мой пост не предназначен для непосредственного тестирования логики контроллера.
Юнит-тест должен проходить именно так, как следует из названия, и тестировать «Один юнит» Если я тестирую контроллер (как вы делаете выше), я забываю все о доступе к данным. Я должен был удалить все вызовы контекста базы данных в моем уме и заменить их вызовом метода черного ящика, как если бы эти операции были мне неизвестны. Это код вокруг тех операций, которые я заинтересован в тестировании.
Пример:
В моем приложении MVC мы используем шаблон репозитория. У меня есть хранилище, скажем CustomerRepository: ICustomerRepository, которое будет выполнять все операции с моей базой данных клиентов.
Если бы я хотел проверить свои контроллеры, хотел бы я, чтобы тесты проверяли мой репозиторий, доступ к базе данных и саму логику контроллера? конечно нет! в этом конвейере много «юнитов». То, что вы хотите сделать, это создать поддельное хранилище, которое реализует ICustomerRepository, чтобы позволить вам тестировать логику контроллера в отдельности.
Насколько я знаю, это нельзя сделать только в контексте базы данных. (за исключением, может быть, для использования Microsoft Moles, которые вы можете проверить, если хотите). Это просто потому, что все запросы выполняются вне контекста в вашем классе контроллера.
Если бы я хотел проверить логику CustomerRepository, как бы я это сделал? Самый простой способ - использовать поддельный контекст. Это позволит мне убедиться, что когда я пытаюсь получить клиента по идентификатору, он фактически получает клиента по идентификатору и так далее. Методы репозитория очень просты, и проблема «Невозможно перевести в выражение магазина» обычно не возникает. Хотя в некоторых незначительных случаях это может (иногда из-за неправильно написанных запросов linq) в этих случаях важно также выполнять интеграционные тесты, которые будут проверять ваш код на всем пути к базе данных. Эти проблемы будут найдены в интеграционном тестировании. Я использовал эту технику N-Layered довольно давно и не нашел никаких проблем с этим.
Интеграционные тесты
Очевидно, что тестирование вашего приложения на базе самой базы данных является дорогостоящим упражнением, и, как только вы получите десятки тысяч тестов, это станет кошмаром, с другой стороны, оно лучше всего имитирует, как код будет использоваться в «реальном мире». Эти тесты также важны (от пользовательского интерфейса до базы данных) и будут выполняться как часть интеграционных тестов, а НЕ модульных тестов.
Acaz, в твоём сценарии действительно нужен репозиторий, который можно смоделировать / подделать. Если вы хотите протестировать свои контроллеры так, как вы это делаете, тогда ваш контроллер должен принимать объект, который оборачивает функциональность базы данных. Затем он может вернуть все, что вам нужно, чтобы протестировать все аспекты функциональности вашего контроллера.
см. http://msdn.microsoft.com/en-us/library/ff714955.aspx
Для того, чтобы протестировать сам репозиторий (обсуждаемый при необходимости во всех случаях), вам нужно либо подделать контекст, либо использовать что-то в соответствии с рамками Moles.
LINQ сложно тестировать. Тот факт, что запрос определяется вне контекста с использованием методов расширения, дает нам большую гибкость, но создает кошмар для тестирования. Оберните ваш контекст в хранилище, и эта проблема исчезнет.
извините так долго :) 1040 *