Предпочитайте тестирование интерфейса, а не тестирование на реализации.
Насколько я понимаю, частные методы не тестируются
Это зависит от вашей среды разработки, см. Ниже.
[частные методы] не должны беспокоиться, потому что общедоступный API предоставит достаточно информации для проверки целостности объекта.
Правильно, TDD фокусируется на тестировании интерфейса.
Частные методы - это детали реализации, которые могут меняться в течение любого цикла перефакторинга. Должна быть возможность перефакторинга без изменения интерфейса или поведения черного ящика . Фактически, это является частью преимущества TDD, легкость, с которой вы можете создать уверенность в том, что внутренние изменения в классе не повлияют на пользователей этого класса.
Что ж, я могу создать объект, который имеет только частные методы и взаимодействует с другими объектами, слушая их события. Это было бы очень инкапсулировано, но совершенно не поддается проверке.
Даже если у класса нет открытых методов, его обработчики событий являются его общедоступным интерфейсом и противоречат тому общедоступному интерфейсу, который вы можете проверить.
Поскольку события являются интерфейсом, то именно эти события вам нужно будет генерировать для проверки этого объекта.
Изучите использование фиктивных объектов в качестве клея для вашей тестовой системы. Должна быть возможность создать простой фиктивный объект, который генерирует событие и улавливает результирующее изменение состояния (возможно, другим фиктивным объектом приемника).
Также считается плохой практикой добавлять методы ради тестирования.
Безусловно, вы должны быть очень осторожны в разоблачении внутреннего состояния.
Значит ли это, что TDD расходится с инкапсуляцией? Каков соответствующий баланс?
Точно нет.
TDD не должен изменять реализацию ваших классов иначе как для упрощения их (применяя YAGNI с более ранней точки).
Лучшая практика с TDD идентична лучшей практике без TDD, вы просто узнаете, почему раньше, потому что вы используете интерфейс при его разработке.
Я склонен обнародовать большинство или все мои методы сейчас ...
Это было бы лучше, если бы ребенок вылил воду в ванну.
Вам не нужно обнародовать все методы, чтобы вы могли разрабатывать их в формате TDD. Посмотрите мои заметки ниже, чтобы увидеть, действительно ли ваши частные методы не поддаются проверке.
Более детально рассмотрим тестирование приватных методов
Если вам абсолютно необходимо выполнить модульное тестирование некоторого личного поведения класса, в зависимости от языка / среды, у вас может быть три варианта:
- Поместите тесты в класс, который вы хотите проверить.
- Поместите тесты в другой файл класса / исходного кода и предоставьте приватные методы, которые вы хотите протестировать, как публичные методы.
- Используйте среду тестирования, которая позволяет разделить тестовый и рабочий код, но при этом разрешить тестировать доступ к частным методам рабочего кода.
Очевидно, что третий вариант является безусловно лучшим.
1) Поместите тесты в класс, который вы хотите протестировать (не идеально)
Хранить тестовые случаи в том же файле класса / исходного кода, что и тестируемый производственный код, - самый простой вариант. Но без большого количества препроцессорных директив или аннотаций вы в конечном итоге получите тестовый код, который будет лишним раздувать ваш производственный код, и в зависимости от того, как вы структурировали свой код, вы можете в конечном итоге случайно раскрыть внутреннюю реализацию пользователям этого кода.
2) Выставьте приватные методы, которые вы хотите протестировать, как публичные (на самом деле не очень хорошая идея)
Как и предполагалось, это очень плохая практика, разрушает инкапсуляцию и раскрывает внутреннюю реализацию пользователям кода.
3) Используйте лучшую среду тестирования (лучший вариант, если он доступен)
В мире Eclipse, 3. может быть достигнуто с помощью фрагментов . В мире C # мы могли бы использовать частичные классы . Другие языки / среды часто имеют схожую функциональность, вам просто нужно ее найти.
Слепое предположение о том, что единственными вариантами являются 1. или 2., может привести к тому, что производственное программное обеспечение будет раздуто с помощью тестового кода или неприятных интерфейсов классов, которые стирают грязное белье в общественных местах. * 8' )
- В общем, гораздо лучше не проверять частную реализацию.