Как писать тестируемый код

Я придерживаюсь правил, которые сформулировал Misko Hevery.

Объект не должен создавать другие объекты

Все зависимости должны передаваться через конструктор. Желательно, с помощью Dependency Injection библиотеки. Поначалу это выглядит очень странно. Как это, код без new. Но через какое-то время привыкаешь. Получается отличное разделение обязанностей: создание графа объектов отдельно, полезная работа отдельно.

Исключение делается для конечных объектов графа, которые не пользуются другими объектами, а также для стандартных коллекций.

Как правило получается несколько scope’ов. Один граф объектов живет на протяжении всей жизни приложения. Другой создается под обработку каждого HTTP запроса или действия в UI. Если в середине графа необходимо создавать другие объекты в зависимости от условий, то инжектим фабрику.

Объект не должен использовать статические функции и синглтоны

На первый взгляд это правило очевидно. Кто же сейчас пишет статические функции и методы? Но под это определение попадают и способы получения текущего времени/даты. Оборачивать эту функциональность в TimeProvider, и передавать через конструктор тоже странно. Первые несколько раз.

В конструкторе не должно быть никакой реальной работы

Только инициализация мемберов. Разделяем обязанности: вконструкторе только wiring, в остальных методах полезная работа.


Есть и другие правила, но эти — основные. Я использую их когда пишу и на Objective-C, и на Python, и на PHP/Symfony и на JavaScript. Когда есть возможность воткнуть test double через конструктор тесты пишутся намного проще.

Like what you read? Give Краснояров Станислав a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.