Виртуальные методы в конструкторах для TDD с использованием шаблона извлечения и переопределения - PullRequest
1 голос
/ 23 июля 2011

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

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

Мой вопрос заключается в том, перевешивают ли преимущества тестируемого кода проблемучто это может вызвать в будущем?

Ответы [ 3 ]

2 голосов
/ 23 июля 2011

Это проблема, которую энтузиасты TDD часто решают с помощью IoC. Идея состоит в том, что вместо создания объекта, тестируемого в конструкторе, вы передаете его конструктору с помощью контейнера IoC.Затем для тестов вы настраиваете контейнер IoC для использования фиктивного объекта.

2 голосов
/ 23 июля 2011

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

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

Так что избавьтесь от виртуального в конструкторе.

2 голосов
/ 23 июля 2011

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

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

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