Методы разрушения зависимостей с использованием зависимости Inj для модульного тестирования - PullRequest
1 голос
/ 09 марта 2010

В настоящее время читает "Искусство модульного тестирования" Роя Ошерова. Я на полпути к этому, и пока это потрясающая книга. Я собираюсь попросить всех оставить из этого обсуждения контейнеры IOC . Он лишь кратко упоминает о них (фактически заявляет, что МОК выходит за рамки книги, которую я не понимаю, и является одним из немногих мест, где я могу критиковать книгу). В любом случае, за исключением МОК, существуют различные методы:

  1. Конструктор Инъекция
  2. Ввод имущества
  3. Программные фабрики и статика
  4. Программные фабрики и виртуальные методы
  5. Метод инъекции
  6. Элемент списка

Хорошо, я опишу, что мне не нравится в каждом методе выше.
1. Внедрение в конструктор - делает инициализацию объекта запутанной и более сложной, особенно если вам нужно передать много зависимостей.
2. Property Injection - Рою, похоже, нравится эта техника, но она мне менее всего нравится. Если у вас есть куча зависимостей, то пользователь должен не забывать инициализировать каждую и каждую зависимость, которая требуется для класса. Я бы сказал, что это подвержено ошибкам и грязно. Очень затрудняет инициализацию класса для тех, кто не знаком с ним.
3. Программные фабрики и статика - Хотя я не думаю, что это плохая техника, мне не нравится полагаться на состояние. Мне нравится иметь дело с полностью лишенным состояния объектом, но пока я считаю, что это лучшая техника.
4. Программные фабрики и виртуальные методы - Подобно вышеописанным методам, но позволяет вам наследовать от класса и переопределять только функцию, которая устанавливает вашу зависимость, и заменяет ее на заглушки. Мои мысли похожи на 3 - это просто немного запутывает человека, пытающегося выяснить, почему не прошел модульный тест.
5. Внедрение метода - Все, что я могу сказать, это ewwwwwww ... передать каждую и каждую зависимость для каждого метода, который вы вызываете. Достаточно сказано.

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

.InitalizeDepForTesting(IFileSystem file, IDatabase data, IEventLog event, ...)

Затем оберните вышеприведенный оператор в оператор условной компиляции:

#If DEBUG
      public void InitializeDepForTesting(...)
#endIf

Таким образом, ваши внутренние зависимости продолжают работать как есть и не требуют изменений. Вы также предотвращаете испортить конструктор и передать все свои зависимости с кучей других «вещей». Ничего не меняется в том, что касается вашего производственного кода, и очень легко сразу увидеть, как вы должны инициализировать объект для тестирования. Что вы все думаете?

Ответы [ 4 ]

4 голосов
/ 09 марта 2010

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

4 голосов
/ 09 марта 2010

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

Вы просите удалить IoC из обсуждения, но это все равно, что попросить нас обсудить написание кода .Net с помощью Блокнота. Конечно, это можно сделать, но зачем вам это? Контейнер IoC при правильном использовании обычно позволяет во время выполнения собрать все приложение одним вызовом. С этого момента все ваши экземпляры правильно настроены с правильными зависимостями. И это даже не упоминание всей работы, выполняемой с автоматическим издевательством для модульного тестирования.

И, как заметил кто-то другой, если у вас так много зависимостей, что ваши конструкторы сбивают вас с толку, вам действительно нужно переосмыслить свой дизайн. Я бы порекомендовал взять копию «Чистого кода» дяди Боба, когда вы закончите читать прекрасную книгу Роя.

2 голосов
/ 09 марта 2010

а.) Я с толпой PicoContainer об этом: ConstructorInjection - это путь. Четкая семантика и четко определенное исполнение.

b.) О вашем подходе к тестированию: я предпочитаю использовать Mocks, а затем полагаюсь на IOC для сборки объектов.

0 голосов
/ 10 марта 2010

Я попрошу всех покинуть МОК контейнеры из этого обсуждения.

Делая это, вы создаете проблемы. Я понимаю ваши рассуждения, но, все ваши возражения становятся спорными, если вы считаете правильный МОК.

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