Правильное тестирование действий Vuex с помощью Jest

Тестировать действия по отдельности очень просто. Действия должны быть разделены и протестированы независимо от компонентов, которые их отправляют.

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

Создание действия

Мы напишем действие, которое следует общему шаблону Vuex:

  1. сделать асинхронный вызов API
  2. выполнить некоторую обработку данных (необязательно)
  3. совершить мутацию с результатом в качестве полезной нагрузки

Это действие authenticate, которое отправляет имя пользователя и пароль внешнему API, чтобы проверить, совпадают ли они. Затем результат используется для обновления состояния путем фиксации SET_AUTHENTICATED мутации с результатом в качестве полезной нагрузки.

Тест действия должен утверждать:

  1. была использована правильная конечная точка API?
  2. полезная нагрузка правильная?
  3. была ли совершена правильная мутация с результатом

Давайте продолжим и напишем тест, и пусть сообщения об ошибках направят нас.

Написание теста

Поскольку axios является асинхронным, чтобы гарантировать, что Jest ждет завершения теста, нам нужно объявить его как async, а затем await вызов actions.authenticate. В противном случае тест завершится до утверждения expect, и у нас будет вечнозеленый тест - тест, который никогда не может потерпеть неудачу.

Выполнение вышеуказанного теста дает нам следующее сообщение об ошибке:

Эта ошибка возникает где-то изнутри axios. Мы делаем запрос к /api..., и, поскольку мы работаем в тестовой среде, нет даже сервера, к которому можно было бы запросить, и, следовательно, ошибка. Мы также не определили url или body - мы будем это делать, пока будем решать ошибку axios.

Поскольку мы используем Jest, мы можем легко смоделировать вызов API, используя jest.mock. Мы будем использовать фиктивный axios вместо настоящего, что даст нам больше контроля над его поведением. Jest предоставляет Моки класса ES6, которые идеально подходят для имитации axios.

Макет axios выглядит так:

Мы сохраняем url и body в переменных, чтобы мы могли утверждать, что правильная конечная точка получает правильную полезную нагрузку. Поскольку на самом деле мы не хотим попадать в реальную конечную точку, мы немедленно выполняем обещание, которое имитирует успешный вызов API.

yarn unit:test теперь дает успешный тест!

Проверка на ошибку API

Мы протестировали только тот случай, когда вызов API был успешным. Важно проверить все возможные результаты. Напишем тест на случай возникновения ошибки. На этот раз мы сначала напишем тест, а затем реализацию.

Тест можно записать так:

Нам нужно найти способ заставить axios mock выдавать ошибку. Для этого нужна переменная mockError. Обновите макет axios следующим образом:

Jest разрешит доступ к переменной вне области видимости в макете класса ES6, только если к имени переменной добавлено mock. Теперь мы можем просто сделать mockError = true, и axios выдаст ошибку.

Выполнение этого теста дает нам следующую ошибку:

Он успешно обнаружил ошибку… но не ту, которую мы ожидали. Обновите authenticate, чтобы вывести ошибку, ожидаемую тестом:

Сейчас тест проходит.

Улучшения

Теперь вы знаете, как тестировать действия изолированно. Есть по крайней мере одно потенциальное улучшение, которое можно сделать, а именно реализовать axios макет как ручной макет. Это включает в себя создание каталога __mocks__ на том же уровне, что и node_modules, и реализацию там фиктивного модуля.

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

Заключение

В этом руководстве обсуждаются:

  • использование моков класса Jest ES6
  • тестирование как успешных, так и неудачных случаев действия

Исходный код теста, описанного на этой странице, можно найти здесь.

Первоначально опубликовано в Руководстве по тестированию Vue.