Как практикующий" мокист " TDD, должен ли я издеваться над другими методами в том же классе, что и тестируемый метод?
после прочтения Мартина Фаулера насмешки-это не обрубки, я обнаружил, что практикую TDD в "мокистской" манере.
но мне интересно, если даже в mockist TDD, если можно взять насмешку слишком далеко.
здесь обновлено пример псевдо-кода в стиле Python:
def sync_path(self):
if self.confirm_or_create_connection():
self.sync(self.dirpath)
метод confirm_or_create_connection () создает соединение с сервером.
Я тестировал метод, подобный этому, в двух тестах, оба из которых mock confirm_or_create_connection () и sync () (даже если они оба метода в одном классе). В одном тесте макет confirm_or_create_connection() возвращает True и тест подтверждает, что sync() был вызван, а в другом макет confirm_or_create_connection() возвращает False и тест подтверждает, что sync () не был вызван.
разумно ли это? Или я должен издеваться над объектами, которые confirm_or_create_connection() и sync () вызывают? (У меня есть другие тесты обоих эти методы, которые уже делают это.)
пожалуйста, не отвечайте на вопрос, объясняя, что вместо этого я должен практиковать "классический" TDD. Это ответ на другой вопрос:--18-->должен ли я практиковать mockist или классический TDD?
7 ответов
техника называется "макет объектов", а не" макет методов " по какой-либо причине. Он поощряет проекты, которые разделяют систему на легко составленные, сотрудничающие объекты и вдали от процедурного кода. Цель состоит в том, чтобы поднять уровень абстракции так, чтобы вы в основном программировали, составляя объекты, и редко писали низкоуровневые операторы потока управления.
лично я думаю, что издевательство над собой почти всегда является запахом кода. Это проверка реализации, а не поведения.
отредактировано для обновленного образца:
теперь понятно. У вас есть проблемы с тестированием этого класса, потому что у него есть недостатки дизайна. Этот класс нарушает принцип единой ответственности. Он делает две вещи. Во-первых, это управление подключением к базе данных. Он также синхронизируется.
нужен отдельный класс для управления подключением к базе данных. Этот класс будет зависимостью тестируемого класса. Класс подключения базы данных может быть подделан при модульном тестировании класса испытываемый.
ранее:
как тестер взаимодействия коллег, рефакторинг, если у вас есть нужно сделать это. Этот класс наверное, делает слишком много.
скажем так: звоню частный метод не делает взаимодействие.
Это один из основных пунктов TDD. Когда больно ваш дизайн может быть улучшенный.
отредактировано для нового примера
Мне кажется, что вы stubbing confirm_or_create_connection, вас интересует только определение обратного вызова, и вы издеваетесь над синхронизацией, здесь вам интересно проверить, действительно ли он вызван. (Мне нужно будет проверить, совпадает ли мое определение stubbing или mocking с статьей Фаулера, на которую вы ссылались. Прошло некоторое время с тех пор, как я прочитал его, и я использовал rhinomocks в C# , который может иметь собственную защиту этих терминов : -))
Я думаю, что то, что вы тестируете, издеваясь и заглушая эти звонки, - правильный путь. Вы не хотите тестировать сбой, если одна из этих функций имеет ошибку, для этого есть другие тесты. Вы просто хотите проверить работу sync_path.
Я согласен с Avdi, что это довольно вонючий. Тесты в порядке, но ваш класс может делать слишком много.
угадывая дико, похоже, что действие соединения может принадлежать другому объекту, которому следует делегировать, и в этом случае вы можете издеваться что. Я обычно рекомендую не издеваться над одной частью объекта, чтобы проверить другую часть. Это говорит о том, что существуют две концепции, связанные вместе.
вы можете взять насмешки слишком далеко? Я не знаю о слишком далеко, но это может быть сделано плохо, так что вы на самом деле тестируете насмешки вместо кода или хуже, так что у вас есть хрупкие тесты.
но пока вы пишете хорошие тесты-тесты, которые подтверждают ваше ожидаемое поведение, тесты, которые помогают вам писать код - тогда издевайтесь!
вот хорошее чтение на нем: "принцип: Не изменяйте SUT" at http://xunitpatterns.com/Principles%20of%20Test%20Automation.html#Don
изменение класса, который вы тестируете, насмехаясь или заглушая части его реализации, является запахом кода. Рефакторинг, чтобы уйти от него, - это переместить часть, которую вы насмехаетесь/тушите, в другой класс. Это говорит о том, что это не всегда ужасно. Это кодовый запах, но не всегда неуместный. Для таких языков, как C# или Java, где у вас есть хорошие инструменты рефакторинга, легко исправить этот запах кода, и я обычно (в C#, предполагая, что Java аналогична). Я делаю много разработки в Lua и Javascript, хотя, где все немного по-другому. Создание и управление множеством классов на этих языках сложнее, поэтому я более терпим к изменению SUT в тестах. Его всегда что-то я могу исправить позже, как только начальное покрытие теста там. Это требует дополнительного ухода.