модульный тест запаха - PullRequest
5 голосов
/ 29 июня 2009

Я пытаюсь изменить свое модульное тестирование ArcGIS и начать использовать макеты (я использую Rhino).
Когда я начал писать тесты, я заметил, что должен начать насмехаться над многими объектами и заглушить множество методов, чтобы пройти даже один тест.
Например - мой контроллер сначала получает RelationshipClass (поэтому мне нужно заглушить IWorkspace и возвращенный IRelationshipClass), затем также получает IFeature (заглушку) и, наконец, вызывает stubRelClass.GetRelatedObjects(stubFeature), чтобы вернуть ISet других IFeatures.

Это нормально, когда нужно заглушить так много объектов и методов, чтобы он прошел? Я тоже чувствую как будто мне действительно нужно перешагнуть код (да - я знаю, что я должен был сначала написать тесты, я все еще пробую этот), чтобы выяснить, что нужно заглушить следующим, и что я должен вернуть.

У меня также возникают проблемы с классами mocking com, которые реализуют более одного интерфейса. В рабочем коде я QI их между интерфейсами. Как я могу создать макет, который реализует оба интерфейса во время выполнения?

Ответы [ 3 ]

3 голосов
/ 29 июня 2009

Это может быть признаком высокой связи - что, в свою очередь, подразумевает необходимость уменьшения зависимостей (что улучшит дизайн и тестируемость). В качестве приблизительного ориентира, объект должен иметь максимум 4-6 сотрудников. Что-нибудь сверх этого вызвало бы мою тревогу.

Как использовать Mocks?

3 голосов
/ 29 июня 2009

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

Вы также должны быть в состоянии выполнить большую часть ваших насмешек методом [SetUp], а затем каждый тест просто изменить одну или две вещи.

Для моделирования нескольких интерфейсов Rhino имеет концепцию MultiMock. Я полагаю, что вы используете следующий синтаксис:

var mock = 
    MockRepository.DynamicMultiMock<MyType>(
              typeof(Interface1), 
              typeof(Interface2), 
              ....);
2 голосов
/ 29 июня 2009

Для меня это звучит как непроверяемый код, который является запахом :-(

Я бы порекомендовал прочитать http://misko.hevery.com/code-reviewers-guide/. Автор является тренером, ответственным за обучение разработчиков Google в области тестирования. В статье он показывает, как можно писать тестируемый и непроверяемый код.

Дальнейшее рекомендуемое чтение: Чистый код (Роберт С. Мартин) - основное внимание уделяется написанию чистого (соответствующего тестируемому) кода. Эффективная работа с устаревшим кодом (Майкл Фезер) - показывает способы получить контроль над непроверенным и непроверяемым кодом.

...