Віддайте перевагу тестуванню інтерфейсу, ніж тестуванню на реалізацію.
Наскільки я розумію, що приватні методи не піддаються конкуренції
Це залежить від вашого середовища розробки, див. Нижче.
[приватні методи] не повинні турбуватися, оскільки загальнодоступний API надасть достатньо інформації для перевірки цілісності об'єкта.
Правильно, TDD зосереджується на тестуванні інтерфейсу.
Приватні методи - це деталізація реалізації, яка може змінюватися протягом будь-якого циклу рефактора. Повинно бути можливим повторний фактор, не змінюючи інтерфейс чи поведінку чорного поля . Насправді, це є частиною переваги TDD, простота, з якою ви можете створити впевненість, що внутрішні зміни класу не вплинуть на користувачів цього класу.
Ну, для мене можливо зробити об’єкт, який має лише приватні методи та взаємодіє з іншими об’єктами, слухаючи їх події. Це було б дуже інкапсульовано, але абсолютно не піддавалося.
Навіть якщо у класу немає публічних методів, це обробники подій - це публічний інтерфейс , і це проти того публічного інтерфейсу, який ви можете протестувати.
Оскільки події є інтерфейсом, то для тестування цього об’єкта вам потрібно буде генерувати події.
Погляньте на використання макетних предметів як клею для вашої тестової системи. Повинно бути можливим створити простий макетний об’єкт, який генерує подію і підбирає результуючу зміну стану (можливо іншим об'єктом макету приймача).
Також вважається поганою практикою додавати методи заради тестування.
Абсолютно, вам слід дуже обережно викривати внутрішній стан.
Чи означає це, що TDD суперечить інкапсуляції? Який відповідний баланс?
Абсолютно ні.
TDD не повинен змінювати реалізацію ваших класів, крім того, щоб можливо спростити їх (застосувавши YAGNI з попередньої точки).
Найкраща практика з TDD є ідентичною найкращій практиці без TDD, ви просто дізнаєтеся, чому раніше, оскільки ви використовуєте інтерфейс під час його розробки.
Я схильний оприлюднити більшість чи всі мої методи зараз ...
Це було б скоріше викинути дитину разом з водою з ванни.
Вам не потрібно оприлюднювати всі методи, щоб ви могли розвиватися TDD. Перегляньте мої нотатки нижче, щоб побачити, чи справді ваші приватні методи не можна визначити.
Більш детально розглянути тестування приватних методів
Якщо ви абсолютно зобов'язані перевірити приватну поведінку класу, залежно від мови / середовища, у вас можуть бути три варіанти:
- Поставте тести в клас, який ви хочете пройти.
- Помістіть тести в інший клас / вихідний файл та відкрийте приватні методи, які ви хочете перевірити як публічні методи.
- Використовуйте тестове середовище, що дозволяє зберігати тестовий і виробничий код окремо, але все ж дозволяють тестувати код доступу до приватних методів виробничого коду.
Очевидно, що 3-й варіант на сьогоднішній день найкращий.
1) Поставте тести в клас, який ви хочете протестувати (не ідеально)
Зберігання тестових випадків у тому ж класі / вихідному файлі, що і тестовий код виробництва, є найпростішим варіантом. Але без великої кількості попередніх процесорних інструкцій чи приміток, ви отримаєте тестовий код, який надмірно розмиває ваш виробничий код, і залежно від того, як ви структурували свій код, ви можете випадково піддавати внутрішню реалізацію користувачам цього коду.
2) Розкрийте приватні методи, які ви хочете перевірити як публічні методи (насправді це не дуже гарна ідея)
Як було запропоновано, це дуже погана практика, руйнує інкапсуляцію та піддається внутрішній реалізації користувачам коду.
3) Використовуйте краще середовище для тестування (найкращий варіант, якщо він є)
У світі затемнення 3. можна досягти, використовуючи фрагменти . У світі C # ми можемо використовувати часткові класи . Інші мови / середовища часто мають подібний функціонал, просто потрібно його знайти.
Сліпо припустивши, що 1. або 2. є єдиними варіантами, які, ймовірно, призведуть до того, що виробниче програмне забезпечення, роздуте тестовим кодом, або неприємні інтерфейси класу, які миють брудну білизну на публіці. * 8 ')
- Загалом - все-таки краще не перевіряти приватну реалізацію.