Я використовую підхід, схожий на підхід Джона, але замість того, щоб створювати спеціалізований інтерфейс лише на поточний час (скажімо, Clock
), я зазвичай створюю спеціальний інтерфейс тестування (скажімо, MockupFactory
). Я помістив туди всі методи, які мені потрібні для тестування коду. Наприклад, в одному зі своїх проектів у мене є чотири методи:
- той, який повертає макет клієнта бази даних;
- той, який створює макет об’єкта-сповіщувача, який повідомляє код про зміни в базі даних;
- той, який створює макет java.util.Timer, який запускає завдання, коли я цього хочу;
- той, що повертає поточний час.
Тестований клас має конструктор, який приймає цей інтерфейс серед інших аргументів. Той без цього аргументу просто створює екземпляр цього інтерфейсу за замовчуванням, який працює "в реальному житті". І інтерфейс, і конструктор є приватними для пакету, тому API тестування не витікає за межі пакету.
Якщо мені потрібні більш імітовані об'єкти, я просто додаю метод до цього інтерфейсу та впроваджую його як у тестуванні, так і в реальних реалізаціях.
Таким чином я розробляю код, придатний для тестування, в першу чергу, не накладаючи занадто багато на сам код. Насправді, таким чином код стає ще чистішим, оскільки багато заводських кодів зібрано в одному місці. Наприклад, якщо мені потрібно перейти до іншої реалізації клієнта бази даних у реальному коді, мені потрібно лише змінити лише один рядок, замість того, щоб шукати посилання на конструктор.
Звичайно, як і у випадку з підходом Джона, він не буде працювати зі стороннім кодом, який ви не можете або не можете змінити.