Я делаю что-то принципиально неправильное в моих юнит-тестах? - PullRequest
12 голосов
/ 30 августа 2010

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

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

Ответы [ 4 ]

5 голосов
/ 30 августа 2010

когда я создаю тест, в котором используется макет, я записываю все вызовы в конкретный макет и присваиваю возвращаемые значения

Звучит так, как будто вы переоцениваете ожидания.

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

Этот ответ включает краткий пример (а также альтернативное, более подробное объяснение).

4 голосов
/ 30 августа 2010

Мой опыт состоит в том, чтобы использовать макеты только в границах (подс) систем. Если у меня есть два тесно связанных класса, я не смеюсь над ними, а проверяю их вместе. Примером может быть составной и посетитель. Если я тестирую конкретного посетителя, я не использую макет для композита, но создаю реальные композиты. Можно утверждать, что это не юнит-тест (зависит от определения того, что такое юнит). Но это не так важно. То, что я пытаюсь достичь, это:

  1. Пишите читаемые тесты (тесты без макетов в большинстве случаев легче читать).
  2. Проверка только сфокусированной области кода (в примере конкретный посетитель и соответствующая часть композита).
  3. Пишем быстрые тесты (пока я создаю экземпляры только нескольких классов, в примере конкретные композиты, это не проблема ... следите за переходными созданиями).

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

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

3 голосов
/ 30 августа 2010

Если вы исправляете тесты, потому что они ломаются, вы не используете их по назначению.

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

0 голосов
/ 30 августа 2010

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

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