Должен ли я, издеватель-практик по TDD, издеваться над другими методами того же класса, что и тестируемый метод? - PullRequest
9 голосов
/ 09 октября 2008

После прочтения "1001 * Мокков не заглушки" Мартина Фаулера я обнаружил, что я практикую TDD в "модернистской" манере.

Но мне интересно, можно ли даже в издевательской программе TDD зайти слишком далеко.

Вот пример обновленный в псевдокоде в стиле Python:

def sync_path(self):
    if self.confirm_or_create_connection():
        self.sync(self.dirpath)

Метод verify_or_create_connection () создает соединение с сервером.

Я проверил метод, подобный этому, в двух тестах, оба из которых имитируют verify_or_create_connection () и sync () (даже если они оба метода в одном классе). В одном тесте mock verify_or_create_connection () возвращает True, и тест подтверждает, что sync () был вызван, а в другом mock verify_or_create_connection () возвращает False, и тест подтверждает, что sync () не был вызван.

Это разумно? Или я должен насмехаться над объектами, которые подтверждают, которые подтверждают, или вызывают () синхронизация ()? (У меня есть другие тесты обоих этих методов, которые уже делают это.)

Пожалуйста, не отвечайте на вопрос, объясняя, что вместо этого я должен практиковать «классический» TDD. Это ответ на другой вопрос: Должен ли я практиковаться в моде или классическом TDD?

Ответы [ 7 ]

8 голосов
/ 23 мая 2009

Техника называется «фиктивные объекты», а не «фиктивные методы» по причине. Это поощряет проекты, которые делят систему на легко составленные, взаимодействующие объекты и не связанные с процедурным кодом. Цель состоит в том, чтобы поднять уровень абстракции, чтобы вы в основном программировали путем составления объектов и редко писали операторы низкоуровневого потока управления.

5 голосов
/ 09 октября 2008

Лично я считаю, что издевательство над собой - это почти всегда запах кода. Это тестирование реализации, а не поведения.

4 голосов
/ 15 мая 2009

Отредактировано для обновленного образца:

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

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

Ранее:

Как собеседник по взаимодействию, рассмотреть возможность рефакторинга, если у вас есть нужно сделать это. Этот класс вероятно, слишком много.

Позвольте мне выразить это так: частный метод не делает взаимодействие.

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

1 голос
/ 21 мая 2009

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

1 голос
/ 09 октября 2008

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

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

Я согласен с Авди, что это отчасти вонючий. Тесты в порядке, но ваш класс может делать слишком много.

0 голосов
/ 19 февраля 2010

Вот хорошее прочтение: «Принцип: не изменяйте SUT» на http://xunitpatterns.com/Principles%20of%20Test%20Automation.html#Don

Изменение класса, который вы тестируете, путем насмешки или недоработки частей его реализации - запах кода. Рефакторинг, чтобы убежать от него - переместить часть, над которой вы издеваетесь / заглушить, в другой класс Тем не менее, это не всегда ужасная вещь. Это запах кода, но это не всегда неуместно. Для таких языков, как C # или Java, где у вас есть хорошие инструменты рефакторинга, легко исправить этот запах кода, и я обычно это делаю (в C # при условии, что Java похожа). Я много занимаюсь разработкой в ​​Lua и Javascript, где все немного по-другому. Создание и управление множеством классов на этих языках сложнее, поэтому я более терпим к изменению SUT в тестах. Это всегда что-то, что я могу исправить позже, когда начальное тестовое покрытие будет там. Это требует особого ухода.

0 голосов
/ 17 ноября 2008

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

Но пока вы пишете хорошие тесты - тесты, которые подтверждают ваше ожидаемое поведение, тесты, которые помогают вам писать код, - тогда издевайтесь!

...