Внедрение зависимостей в NerdDinner - фактически тестирование вашего хранилища или модели - PullRequest
7 голосов
/ 10 октября 2009

Рассмотрим новичка, имеющего дело с инъекцией зависимостей. Мы анализируем два соответствующих класса в NerdDinner.

DinnerRepository из приложения: Repo image

FakeDinnerRepository из тестов: Fakes image

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

Я понимаю, что тест предназначен для контроллера, но я обеспокоен тем, что есть две разные реализации логики доступа к данным. Рассмотрим любой проект, который использует любой тип ORM, ADO.NET, SubSonic или любой другой тип доступа к данным, который вам нравится. Да, вы можете настроить свой поддельный репозиторий в соответствии с реальным репо.

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

Вопросы:

  • Как бы вы протестировали модель в этом случае?
  • Уместно ли протестировать модель?
  • Это вопрос дисциплины, чтобы ваш тест соответствовал реализации бизнес-логики?

Ответы [ 2 ]

4 голосов
/ 11 октября 2009

Возможно, это не полный ответ на ваш вопрос, но я постараюсь пройти часть пути туда.

Интерфейс - в данном случае IDinnerRepository - должен рассматриваться как контракт . Это означает, что любая реализация должна выполнить этот контракт. Если метод FindAllDinners (), то это в основном то, что он должен делать. Поддельный репозиторий, используемый для модульных тестов, обычно может быть НАМНОГО проще, чем реальная вещь (например, с использованием словаря), поэтому не следует воспринимать реальную реализацию как проблему, скорее, рассматривайте это как требование.

Причиной существования поддельного хранилища является тестирование. В основном, все, что может быть проверено, должно быть проверено. А изъятие базы данных из уравнения - это точка ложного хранилища в памяти. Доступ к данным не является целью теста, поэтому мы заменим его. Поддельный репозиторий намного быстрее настраивается и используется, и мы можем легко убедиться, что репозиторий находится в состоянии, необходимом для прохождения тестируемого кода.

Итак, вы должны передать модели копию вашего поддельного репозитория в модульных тестах и ​​убедиться, что все, что происходит в коде модели, отражено в поддельном репозитории.

Думаю, вы обнаружите, что на практике синхронизировать репозитории не составит труда. Если требования изменятся, вы измените интерфейс, и обе реализации должны будут измениться. Если намерения изменятся, вы, вероятно, дойдете до того момента, когда ваши модульные тесты начнут ломаться.

Надеюсь, это поможет!

2 голосов
/ 30 декабря 2009

Ничего не стоит, что FakeDinnerRepository должен тестировать код, который требует IDinnerRepository. Не проверять сам DinnerRepository. Если бы мы использовали настоящий обеденный репозиторий для тестирования таких вещей, как DinnerController, мы бы тестировали не только функциональность DinnerController, но и сам доступ к данным. Хотя биты доступа к данным, безусловно, должны быть проверены, они не должны проверяться в тестах контроллера обеда.

Проверка вашего доступа к данным - довольно спорная тема. Я полагаю, что причина, по которой большинство людей исключают его из своих модульных тестов, заключается в том, что для его выполнения требуется гораздо больше времени. Необходимость запроса к базе данных добавит массу времени к вашему тестированию, которое большинство разработчиков предпочли бы не выдержать.

Независимо от того, проверен ли ваш доступ к данным в модульных тестах или более формальное функциональное тестирование, решать только вам. Но это, безусловно, необходимо проверить. Лично я фанат проведения транзакционных модульных тестов для уровня доступа к данным. Просто убедитесь, что вы только тестируете свои запросы, а не проверяете, работает ли ваш ORM так, как он должен (это работа ORMs).

...