DevGang
Авторизоваться

Mock Dependency: секретное оружие для Vue Unit Tests 

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

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

В этой статье я покажу вам, как смоделировать файл модуля в Jest, заменив его на графике зависимостей вашего компонента.

Пример сценария

Скажем, у нас есть однофайловый компонент, который мы хотим протестировать, который называется Home.vue . Этот компонент является частью блогового приложения, и его основной задачей является отображение заголовков сообщений.

Для этого он извлекает сообщения, импортируя Vuex ORM модель Post и вызывая ее метод all. Неважно, если вы не знакомы с Vuex ORM, важно то, что модель Post является зависимостью этого компонента.




Модульный тест

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

Детали этого теста не важны, но вот как мы могли бы написать его. Сначала мы смонтировали компонент, используя Vue Test Utils. Во-вторых, мы будем проверять смонтированный компонент по снимку его визуализированной разметки.

import { shallowMount } from "@vue/test-utils";
import Home from "@/views/Home";

describe("Home.vue", () => {
  it("should render correctly", () => {
    wrapper = shallowMount(Home);
    expect(wrapper).toMatchSnapshot();
  });
});

Ошибка теста

Если мы попытаемся запустить этот тест, мы получим ошибку:

"TypeError: Cannot read property 'store' of undefined"

Причина этой ошибки заключается в том, что модель Post в компоненте зависит как от Vuex ORM, так и от Vuex, и ни один плагин не присутствует в тестовом экземпляре Vue.

computed: {
  posts () {
    // ожидает установки плагинов VuexORM и Vuex
    Post.all();
  }
}

Mock

У вас может возникнуть желание установить VuexORM и Vuex на тестовом экземпляре Vue. Проблема с этим подходом состоит в том, что ошибки не остановятся на этом; затем он будет жаловаться на то, что хранилище Vuex не было создано, а затем на то, что модель не была установлена ​​в базу данных Vuex ORM и т. д. Внезапно у вас в тесте 20 строк кода и много сложностей.

Но вот в чем дело: для этого модульного теста не важно, чтобы сообщения приходили из хранилища Vuex. Все, что нам нужно сделать, это удовлетворить зависимость, поэтому мы обратимся к мокам.

Создание мока

Самый простой способ создать мок, это сначала создать каталог mocks. Затем создайте мок модуля в этом новом каталоге. Если вы будете следовать этому рецепту, Jest автоматически подберет файл.

mkdir src/store/models/__mocks__
touch src/store/models/__mocks__/Post.js

Внутри нового файла экспортируйте модуль Common JS. Чтобы мок работал, вам нужно добавить заглушку метод модели Post, который вызывает компонент.

Единственный метод, используемый в компоненте - это all. Этот метод будет извлекать все элементы в хранилище. Выходные данные этого метода затем используются для обработке в v-for. Итак, все, что нам нужно сделать, это сделать функцию all, которая возвращает массив, и  компонент Home будет счастлив.

src/store/models/__mocks__/Post.js

module.exports = {
  all: () => []
};

Как мок разрешает зависимости

Теперь мы хотим сделать так, чтобы компонент Home использовал фиктивную модель Post вместо «реальной» модели.

Прежде чем я покажу вам, как это сделать, мне нужно кратко объяснить, как Jest и Webpack, строит график зависимостей при запуске тестового кода. Другими словами, он начинается с вашего тестового файла, затем следует за каждым оператором import и require, отмечая каждый необходимый модуль.

В настоящее время одним из путей этого графа зависимостей, относящихся к тому, что мы обсуждаем, будет следующий:

Home.spec -> Home -> Post -> Vuex ORM -> Vuex -> ...

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

К счастью, Jest позволяет нам заменять модули в графе зависимостей теми, которые мы указываем. Если мы используем наш мок Post, приведенный выше путь будет изменен так:

Home.spec -> Home -> Post (mock)

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

Использование макета

Чтобы использовать мок, мы используем метод jest.mock. Это идет вверху файла, так как обрабатывается в то же время, что операторы import и require.

Первый аргумент является модулем, который вы хотите заменить, в этом случае "@/store/models/Post". Если вы поместите макет в каталог __mocks__, как описано выше, это все, что требуется для его работы.

import { shallowMount } from "@vue/test-utils";
import MyComponent from "@/MyComponent";

jest.mock("@/store/models/Post");

describe("MyComponent.vue", () => {
  it("should render correctly", () => {
    wrapper = shallowMount(MyComponent);
    expect(wrapper).toMatchSnapshot();
  });
});

При выполнении этого теста снова, Jest обеспечит замену нашей зависимости на "@/store/models/Post" с моком который вы создали, и вместо TypeError, вы получите пройденный тест.

Источник:

#Vue.js
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

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

Попробовать

В этом месте могла бы быть ваша реклама

Разместить рекламу