Какие проблемы решает jest.fn()?

Может быть, я такой тупой, но я не могу понять, что именно jest.fn() делает и как он используется. Я новичок в тестировании, и в основном у меня есть большая часть функциональности jest, но jest.fn() заставляет меня дрожать.

Я пытался обращаться к документам, смотреть руководства, но все, что я знаю на данный момент, это то, что jest.fn() может шпионить за функцией или методом.

Зачем нам это нужно, если мы можем проверить возвращаемое значение с помощью .toBe или .toEqual, проверить его существование с помощью .toBeDefined() и его параметры с помощью .toBeCalledWith()?

Я борюсь с этим около недели. Я определенно что-то упускаю, но мне не у кого спросить.


person Alexander Prisazhny    schedule 28.07.2018    source источник
comment
Слышали ли вы о фиктивных функциях? Связанная страница документа содержит хороший пример использования jest.fn, чтобы увидеть, выполняется ли обратный вызов, переданный функции (и с каким параметром он был вызван). Шпионаж, т.е. с .toBeCalledWith() также доступен только для фиктивных функций. Этот SO-вопрос также обсуждает ваш вопрос.   -  person FK82    schedule 28.07.2018
comment
Да, я слышал о них и видел этот пример, но мне чего-то не хватило. Теперь, после объяснения @Sergeon, этот пример имеет для меня смысл.   -  person Alexander Prisazhny    schedule 29.07.2018


Ответы (1)


Проблема, которую призваны решить макеты и заглушки, заключается в том, что вы обычно не хотите действительно вызывать некоторые методы или зависимости в своем тесте, потому что:

  • Они ненадежны, как http-запросы:

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

  • Их сложно настроить в ваших тестах:

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

  • У них есть свои тесты:

    Если вы тестируете модуль карусели, который опирается на модуль i18n, и вы уже тестировали свой модуль i18n, вам не нужно проверять его правильную работу снова. Вы издеваетесь над ним, поэтому вы можете свободно устанавливать модуль i18n и зависимости.

  • Они вычислительно интенсивны:

    Допустим, вы хотите протестировать компонент react/Angular/Vue..., который отображает панель управления пользовательского интерфейса и меню для веб-видеоигры. Вы абсолютно не хотите, чтобы игра действительно работала, пока вы проверяете, что навигационная панель игровой панели ведет себя должным образом.

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

jest.fn(), в частности, делает это на уровне функций. Например, вы тестируете компонент vue, который в своем хуке created() вызывает некоторый метод, который выполняет что-то, с чем вы не хотите иметь дело в своем тесте:

может быть, он вызывает API, возится с локальным хранилищем или делает что-то ресурсоемкое. Таким образом, вы отслеживаете этот метод, помещая jest.fn() на его место, и просто утверждаете, что он вызывается, когда должен.

person Sergeon    schedule 28.07.2018
comment
Потрясающий! Думаю, я наконец понял. Jest.fn() становится дополнением к функциональности, которая нам не нужна в конкретном тесте, и у него есть удобный API для имитации случаев его поведения, верно? - person Alexander Prisazhny; 28.07.2018
comment
Верно! Кроме того, если нас интересует только возвращаемое значение функции, не обращая внимания на ее параметры или зависимости, мы можем настроить jest.fn для возврата определенного значения: jestjs.io/docs/en/mock-functions#mock-return-values - person Sergeon; 28.07.2018
comment
Великолепно! Я не могу быть достаточно благодарен за ваше подробное объяснение наиболее распространенных вариантов использования и основных концепций! - person Alexander Prisazhny; 29.07.2018