Юнит-Тесты Приватных Методов и Абстракций
Большинство специалистов советуют проводить юнит-тесты только публичного API класса. Тестирование закрытых методов приводит к привязке ваших тестов к деталям реализации, что приводит к ложным срабатываниям, что, в свою очередь, снижает точность и ценность теста.
Ценность теста = сигнал/шум,где
-
сигнал – количество найденных ошибок,-
шум – количество ложных срабатываний.Вместо того, чтобы напрямую тестировать закрытые методы, вы должны тестировать их косвенно, как часть общего наблюдаемого поведения (с использованием публичного API класса).
Однако тогда возникают вопросы:
- Что, если закрытые методы содержат важную логику, требующую тестирования?
- Что, если эта логика слишком сложна и её тестирование как часть наблюдаемого поведения класса не обеспечивает достаточного покрытия?
- Как тогда её протестировать?
Обычно такая сложность закрытых методов является признаком отсутствующей абстракции, которую следует выделить в отдельный класс. Допустим, у нас есть класс заказа, в котором есть закрытый метод расчёта стоимости с учётом всех возможных скидок. А публичный API только показывает итоговый результат. В этом случае вместо того, чтобы открывать метод расчёта стоимости, лучше сделать эту абстракцию явной, введя класс «калькулятор стоимости».
Некоторые могут возразить, что извлечение закрытого метода в общедоступный класс не является решением, поскольку вы в любом случае делаете логику общедоступной. Следовательно, раскрытие закрытого метода ничем не отличается от извлечения класса?
Нет. Модульные тесты – не единственная причина, по которой вы могли бы извлечь закрытый метод в класс. Чтобы понять почему, доведём этот аргумент до крайности. Допустим, в вашем проекте нет модульных тестов. Означает ли это, что весь код можно хранить в одном гигантском классе? Вы всё ещё можете разделить его на закрытые методы, так почему бы и нет?
Конечно, это было бы ужасным решением, потому что абстракции (представленные в виде отдельных классов) полезны независимо от того, нужно ли вам тестировать эти абстракции. Они помогают структурировать проект и сохранять контроль над его сложностью.
Таким образом, необходимость модульного тестирования закрытого метода является лишь намёком на отсутствующую (или неуместную) абстракцию. Эта необходимость сама по себе не является требованием для создания такой абстракции.
Другими словами, дизайн кода всегда идёт на первом месте. Модульные тесты просто помогают выявить проблемы с этим дизайном. Даже без модульных тестов было бы неплохо выделить сложный закрытый метод в отдельный класс. Тесты просто явно указывают на это.
Источник: https://www.getdrip.com/deliveries/kjdniknl44vo4fplhd26
Автор оригинала: Vladimir Khorikov