У мене є клас, який реконструюється в 1 основному класі та в 2 менших класах. Основні класи використовують базу даних (як це робить багато моїх класів) і надсилають електронний лист. Таким чином, у основного класу є IPersonRepositoryі IEmailRepositoryвводиться ін'єкція, яка в свою чергу надсилає до 2-х менших класів.
Тепер я хочу провести тест основного класу, і я навчився не тестувати внутрішню роботу класу, тому що ми повинні мати можливість змінювати внутрішні роботи, не порушуючи одиничні тести.
Але , як клас використовує IPersonRepositoryі IEmailRepositoryя МАЮ вказати (макет / манекен) результати для деяких методів для IPersonRepository. Основний клас обчислює деякі дані на основі наявних даних і повертає їх. Якщо я хочу це перевірити, я не бачу, як я можу написати тест, не вказуючи, що IPersonRepository.GetSavingsByCustomerIdreturn x. Але тоді мій блок-тест "знає" про внутрішні розробки, тому що він "знає", які методи знущатися, а які ні.
Як я можу перевірити клас, у якого введені залежності, не знаючи тесту про внутрішню?
фон:
На моєму досвіді безліч тестів на кшталт цього створюють макети для сховищ, а потім або надають потрібні дані для макетів, або тестують, якщо під час виконання було викликано певний метод. Так чи інакше, тест знає про внутрішні.
Тепер я бачив презентацію про теорію (яку я чув раніше), що тест не повинен знати про реалізацію. Спочатку тому, що ви не тестуєте, як це працює, а також тому, що, коли ви зараз змінюєте реалізацію, всі тести блоку виходять з ладу, оскільки вони "знають" про реалізацію. Хоча мені подобається, що концепція тестів не знає про реалізацію, я не знаю, як її виконати.
IPersonRepositoryоб'єкт, цей інтерфейс і всі описані ним методи вже не є "внутрішніми", тому це насправді не є проблемою тесту. Ваше справжнє запитання повинно полягати в тому, "як я можу переробляти класи на менші одиниці, не піддаючись занадто сильному публічному". Відповідь - "тримати ці інтерфейси нахиленими" (наприклад, дотримуючись принципу сегментації інтерфейсу). Це пункт 2 ІМХО у відповіді @ DavidArno (я думаю, немає потреби повторювати це в іншій відповіді).