JS: Продвинутое тестирование
Теория: Манкипатчинг
В некоторых ситуациях инверсия зависимостей подходит идеально, в других из-за нее код становится значительно сложнее и иногда запутаннее, особенно если зависимости требуются где-то глубоко в стеке вызовов (так как придется пробрасывать зависимость через все промежуточные функции). Но есть способ, который позволяет добраться до нужных вызовов и изменить их даже без инверсии зависимостей.
Ниже пример класса, в котором метод делает запрос по сети:
Прототипная модель JS позволяет менять поведение объектов без прямого доступа к ним. Для этого достаточно заменить методы в прототипе. После этого любой объект, имеющий этот прототип, в любой части программы начнет использовать новую реализацию метода.
Используем этот подход, чтобы не дать приложению делать реальный сетевой запрос. Для этого подменим метод:
В тех случаях, когда объект (например, функция-конструктор) используется напрямую, все еще проще, чем с конструктором. Достаточно поменять свойство самого объекта:
Такой подход, когда глобально подменяются значения свойств, называется манкипатчинг (monkey patching). Он считается плохой практикой при написании обычного кода в JS, но он очень популярен и удобен в тестах.
Самый известный пример в JavaScript-мире — библиотека nock. С ее помощью перекрывают реальные сетевые запросы, выполняемые модулем http, который включен в стандартную библиотеку Node.js.
Nock заменяет внутри модуля http некоторые методы, которые используются разными библиотеками для выполнения HTTP-запросов.
И пример использования:
Цепочка nock(domain).get(url) задает полный адрес страницы, запрос к которой надо перехватить. Nock анализирует все выполняемые запросы и подменяет только тот, который соответствует данным параметрам. Домен и адрес страницы могут указываться как целиком, так и через регулярное выражение, чтобы не писать слишком много.
Метод reply(code, body, headers) описывает ответ, который нужно вернуть по данному запросу. В самом простом случае достаточно указать код возврата. В нашей же ситуации кроме кода нужны данные. Именно на этих данных мы и проверяем работу функции getPrivateForkNames().
Здесь мы рассмотрели только самый базовый вариант использования Nock. У этой библиотеки огромная документация и множество вариантов использования. Полезно периодически ее просматривать в поисках более элегантных путей решения задач тестирования.
В чем плюсы и минусы такого способа работы?
Главный плюс в том, что такой способ тестирования практически универсальный. Его можно использовать с любым кодом, без необходимости править сам код. Программа даже не будет догадываться, что ее тестируют.
Минус заключается в том, что тестирование черным ящиком превращается в тестирование прозрачным ящиком. Это значит, что тест знает про устройство тестируемого кода и зависит от внутренностей. Такое знание делает тесты хрупкими. Функция может измениться без потери работоспособности, но тесты придется переписывать, потому что они завязаны на конкретные значения домена, страниц и формата возвращаемых данных.
В большинстве ситуаций это не так критично. Поэтому смело используйте Nock в своих проектах, но не забывайте и про другие способы.








