Работа с приложением на Vue.js с TDD - подробное руководство для людей, у которых есть время - часть 3

Доработка наших компонентов и интеграция магазина

Это третья из серии статей:

Если вы хотите прочитать его в pt-BR, посмотрите здесь.

На прошлой неделе мы провели более простые тесты, связанные с компонентом UserView. Самым интересным из них был рефакторинг, который мы сделали, создав простую базу, которая будет использоваться для тестирования любого компонента в этом проекте.

Давайте теперь углубимся и завершим все тесты компонентов и интегрируем все это с магазином.

Интеграция магазина на наших тестах

Во-первых, давайте изменим наш файл состояния: src/store/state.js

export default {
  user: {},
}

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

Рефакторинг немного длинный. Но давайте разберемся, что здесь сделано.

С помощью shallowMount мы визуализируем только наш компонент, без каких-либо сторонних зависимостей и какой-либо дополнительной конфигурации.

Затем до рефакторинга наш компонент не знал, как использовать Vuex или какие-либо зависимости, мы в итоге установили inmain.js

Благодаря vue-test-utils у нас есть, как создать локальный экземпляр vue, который будет отправлен нашему компоненту. Таким образом, в нашем тесте мы можем указать все зависимости, которые он использует глобально, локально.

  • В строке 9 мы создаем этот локальный экземпляр, делая то же самое, что и main.js во время установки Vuex.
  • В строке 13 мы создаем переменную состояния, которую можно изменять между тестами.
  • В строках 17 e 18 мы отправляем компоненту наш локальный экземпляр vue, точно так же, как новое хранилище (опять же, это именно то, что было сделано onmain.js)
  • В строке 28 мы помещаем beforeEach, поскольку он всегда вызывается между каждым тестом, я пользуюсь возможностью «сбросить» используемые переменные в тестах на стандартное значение. В этом случае мы используем наш исходный файл состояния и сохраняем копию этого файла в нашей переменной состояния между каждым тестом.
  • Наконец, в строке 37 мы можем увидеть одно из преимуществ использования функции build . Здесь мы гарантируем, что перед запуском этого теста мы сбросим state переменную на ее исходное значение. Затем мы можем изменить его значение с помощью нашей фикстуры, содержащей «реальные» данные о нашем поисковом пользователе, и ТОЛЬКО ТОЛЬКО мы сделаем наш компонент build.

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

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

Теперь наш тест не проходит, так как в нашем UserView.vue мы не отправляем через реквизиты VUserProfile.vue пользователя нашего магазина. Давай исправим.

Теперь мы вставляем mapState и сопоставляем свойство user нашего магазина и отправляем его в VUserProfile.

Успех! Теперь мы гарантируем, что UserView отправляет правильное свойство в VUserProfile.

Последний тест UserView

Мы почти закончили работу с нашим компонентом. Отсутствует только одна функция.

Я хочу гарантировать, что всякий раз, когда VUserSearchForm инициирует событие submitted, мы называем его действием магазина, содержащим пользователя, который был введен в него.

Давайте сначала сосредоточимся на тесте:

  • Сначала мы создаем переменную, содержащую пользователя, который должен
    быть отправлен через событие submitted.
  • Сразу после этого мы вручную генерируем настроенное событие компонента VUserSearchForm, что является именно тем событием, которое он сделает в будущем.
  • При этом в строках 50 и 51 мы надеемся, что хранилище action с именем SEARCH_USER было вызвано (запрошено) и что объект, содержащий нашего пользователя, был отправлен как полезная нагрузка
  • Строка 51 может показаться странной, но это форма, которая у нас есть для гарантии того, что мы отправляем правильную полезную нагрузку в действия хранилища, потому что мы не вызываем вручную метод хранилища.

Мы вызываем store.dispatch , а Vuex внутренне вызывает наше действие за нас. И в итоге он вводит в первый параметр объект, в котором мы получаем свойства из Vuex. И как второй параметр, это наша полезная нагрузка.

Затем нам нужно вручную выполнить вызов магазина, получив второй параметр, который является полезной нагрузкой (наше имя пользователя).

Теперь мы можем понять, как шла подготовка к экзамену.

В строке 1, мы используем очень хорошую функциональность шутки. В основном, используя jest.mock, jest возьмет файл в том же каталоге, что и наш импортированный файл, и выполнит поиск src/store/__mocks__/actions.js вместо исходного src/store/actions.js.

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

Это также работает для зависимостей третьих частей. По сути, он будет имитировать для вас все функции зависимостей.

Затем в строке 8 мы импортируем действия нашего магазина, которые на самом деле являются созданным нами фиктивным файлом.

Вставляем действия в магазин в строке 22.

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

Наш тест не проходит. Во-первых, нам нужно гарантировать, что мы работаем с фиктивной функцией.

Здесь мы в основном возвращаем объект с нашей функцией ofSEARCH_USER, возвращающейся к «стандартному» значению, что было бы решенным обещанием с нашим пользователем фикстуры.

Наконец, в нашем UserView мы можем слышать события отправленного, отправленные
VUserSearchForm, и при вызове этого мы можем сделать наш отправка действий.

С помощью этих тестов мы в основном покрываем наш компонент UserView. 😄

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

Я собираюсь опубликовать тестовые и производственные полные файлы напрямую, чтобы эта статья не была ДАЖЕ дольше. Но мы должны следовать тем же пошаговым инструкциям, что и раньше.

Тестирование VUserProfile

Здесь мы не видим ничего нового. Поскольку VUserProfile является компонентом презентации.

Здесь мы добавляем только рендеринг данных, полученных через props.

Итак, мы можем видеть, как все движется. 😏

Тестирование VUserSearchForm

Опять же, тесты здесь очень похожи. Есть только одна хорошая новость, это последняя проверка.

Там мы вручную вставляем во входные данные нашего искомого пользователя, а затем запускаем входные события, указывая, что «мы написали» во входных данных.

И, наконец, кнопка «щелкнуть / отправить», чтобы гарантировать, что событие было выпущено в соответствии с введенным значением.

Таким образом, вы уже изучили основу для тестирования компонентов во Vue. Вполне вероятно, что так будет двигаться и не станет намного сложнее (есть случаи и случаи 😅).

Для производственного кода мы только визуализируем форму, а при отправке выдаем событие отправлено с полезными данными имени пользователя.

Тестирование действия

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

Есть два способа протестировать магазин, и я приведу только один из них. Если вы хотите узнать больше, взгляните на книгу Эдда Йербурга Тестирование приложений Vue.js.

Начнем с проверки наших действий.

В этом случае у нас есть только одно действие. Затем мы вручную вызываем метод SEARCH_USER с имитацией commit, отправляющей наши пользовательские данные.

В строке 20 используется зависимость, которую мы загрузили в начале проекта. Это гарантирует, что все обещания на данный момент выполнены.

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

Кроме того, поскольку мы тестируем только удачный путь, по которому запрос был успешно выполнен, мы надеемся, что наш commit был вызван с нашим приспособлением, где он представляет собой имитацию ответа на Github API.

// src/api.js
export default {}

Поскольку мы используем jest.mock('@/api.js'), нам нужно создать наш фиктивный файл. Позже мы собираемся создать нашу службу запросов, но пока для наших тестов мы можем использовать наш производственный файл только в качестве экспортируемого по умолчанию.

Чтобы не удлинять нашу статью, я собираюсь протестировать только счастливые пути. Мы не собираемся здесь рассматривать альтернативные способы, например сбой запроса, ошибка сети и т. д.

Что ж ... мы только что подошли к этапу:

По сути, нашего метода до сих пор не существует. Наконец-то мы можем сделать нашу реализацию SEARCH_USER production.

Мы можем создавать производственный код разными способами. В этом случае я предпочел вернуть обещание.

И здесь мы делаем все, что нам нужно в нашем тесте. Сначала я вызываю наш api.searchUser, отправляя имя пользователя, которое используется в качестве параметра.

Сразу после получения ответа я совершаю фиксацию мутации, отправляю нашего пользователя и возвращаю службу API.

Идеально! Все тесты пройдены.

Тестирование мутации

Мутация должна быть самым простым случаем, который у нас есть.

Здесь нет никакого секрета. Перед каждым тестом мы сбрасываем наше локальное «состояние», и мы вызываем нашу мутацию напрямую, отправляем это состояние, передавая нашему пользователю.

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

Теперь, когда наш тест не удался, перейдем к реализации.

Выполнено! Я знаю, что в случае Vue.js мне не следует беспокоиться о создании копии объекта, о том, как он работает с реактивностью, но мне лично нравится сохранять мои мутации как чистые функции. Не было бы никаких проблем, если бы вы сделали что-то вроде: state.user = user.

Только не забудьте изменить тест на случай, если захотите.

Наш тест пройден 😄

Обзор

В этой третьей статье мы сделали:

  • Завершено тестирование всех компонентов
  • Интегрировали тесты с магазином

Следите за новостями, на следующей неделе мы завершим наш компонент интеграцией магазина.

Спасибо за внимание, если вам понравилось, нажмите 💚, и любые вопросы, предложения или исправления, не стесняйтесь, присылайте мне сообщение, большое спасибо 😄.

Мой Twitter: @DKuroski

Увидимся на следующей неделе 😄