Если у ваших однофайловых компонентов Vue есть зависимости, вам нужно как-то обрабатывать зависимости при модульном тестировании компонента.
Один из подходов заключается в установке зависимостей в тестовой среде, но это может усложнить ваши тесты.
В этой статье я покажу вам, как смоделировать файл модуля в Jest, заменив его на графике зависимостей вашего компонента.
Пример сценария
Скажем, у нас есть однофайловый компонент, который мы хотим протестировать, который называется Home.vue . Этот компонент является частью блогового приложения, и его основной задачей является отображение заголовков сообщений.
Для этого он извлекает сообщения, импортируя модель Vuex ORM Post
и вызывая ее all
метод. Неважно, если вы не знакомы с Vuex ORM, важно то, что Post
модель является зависимостью этого компонента.
Вам также может понравиться: Vue Development в 2019 году: что нужно знать .
Home.vue
HTML
1
<template>
2
<ul>
3
<li v-for="post in posts">{{ post.title }}</li>
4
</ul>
5
</template>
6
<script>
7
import Post from "@/store/models/Post"
8
export default {
9
computed: {
10
posts () {
11
Post.all();
12
}
13
}
14
}
15
</script>
Модульный тест
Теперь мы хотим написать модульный тест для этого компонента, чтобы убедиться, что он отображается правильно.
Детали этого теста не важны, но вот как мы могли бы написать его. Сначала мы смонтировали компонент, используя Vue Test Utils . Во-вторых, мы будем проверять смонтированный компонент по снимку его визуализированной разметки.
Home.spec.js
JavaScript
xxxxxxxxxx
1
import { shallowMount } from "@vue/test-utils";
2
import Home from "@/views/Home";
3
describe("Home.vue", () => {
5
it("should render correctly", () => {
6
wrapper = shallowMount(Home);
7
expect(wrapper).toMatchSnapshot();
8
});
9
});
Ошибка теста
Если мы попытаемся запустить этот тест, мы получим ошибку:
Простой текст
xxxxxxxxxx
1
"TypeError: Cannot read property 'store' of undefined"
Причина этой ошибки заключается в том, что модель Post Vuex ORM в компоненте зависит как от Vuex ORM, так и от Vuex, и ни один плагин не присутствует в тестовом экземпляре Vue.
JavaScript
xxxxxxxxxx
1
computed: {
2
posts () {
3
// expects VuexORM and Vuex plugins to be installed
4
Post.all();
5
}
6
}
Насмешки на помощь
У вас может возникнуть желание установить VuexORM и Vuex на тестовом экземпляре Vue. Проблема с этим подходом состоит в том, что ошибки не остановятся на этом; затем он будет жаловаться на то, что хранилище Vuex не было создано, а затем на то, что модель не была установлена в базу данных Vuex ORM и т. д. Внезапно у вас в тесте 20 строк кода и много сложностей.
Но вот в чем дело: для этого модульного теста не важно, чтобы сообщения приходили из магазина Vuex. Все, что нам нужно сделать, это удовлетворить зависимость, поэтому мы обратимся к насмешкам.
Создание макета
Самый простой способ создать макет - это сначала создать каталог mocks рядом с файлом, который вы хотите макетировать. Затем создайте макет модуля в этом новом каталоге. Если вы будете следовать этому рецепту, Jest автоматически подберет файл.
Оболочка
xxxxxxxxxx
1
mkdir src/store/models/__mocks__
2
touch src/store/models/__mocks__/Post.js
Внутри нового файла экспортируйте модуль Common JS. Чтобы макет работал, вам нужно заглушить любой метод модели Post, который вызывает компонент.
Единственный метод, используемый в доме - это all
. Этот метод будет извлекать все предметы в магазине. Выходные данные этого метода затем используются для подачи v-for
. Итак, все, что нам нужно сделать, это сделать all
функцию, которая возвращает массив, и Home
компонент будет счастлив.
SRC / магазин / модель / __ издевается __ / Post.js
JavaScript
xxxxxxxxxx
1
module.exports = {
2
all: () => []
3
};
Как шутка разрешает зависимости
Теперь мы хотим сделать так, чтобы Home
компонент использовал фиктивную Post
модель вместо «реальной» Post
модели.
Прежде чем я покажу вам, как это сделать, мне нужно кратко объяснить, как Jest, как и Webpack, строит график зависимостей при запуске вашего тестового кода. Другими словами, он начинается с вашего тестового файла, затем следует за каждым import
и require
оператором, отмечая каждый необходимый модуль.
В настоящее время один путь этого графа зависимостей, относящийся к тому, что мы обсуждаем, будет таким:
Простой текст
xxxxxxxxxx
1
Home.spec -> Home -> Post -> Vuex ORM -> Vuex -> ...
Именно этот путь зависимостей является источником ошибки, с которой мы сталкиваемся.
К счастью, Jest позволяет нам заменять модули в графе зависимостей теми, которые мы указываем. Если мы используем наш Post
макет, приведенный выше путь будет изменен так:
Простой текст
xxxxxxxxxx
1
Home.spec -> Home -> Post (mock)
Суть решения заключается в том, что, в отличие от реальной Post
модели, макет не имеет дальнейших зависимостей, и поэтому TypeError
его больше не должно происходить, если мы его используем.
Использование макета
Чтобы использовать макет, мы используем jest.mock
метод. Это идет вверху файла, так как обрабатывается в то же время, что import
и require
операторы.
Первый аргумент является модулем , который вы хотите , чтобы дразнить, в этом случае "@/store/models/Post"
. Если вы поместите макет в __mocks__
каталог, как описано выше, это все, что требуется для его работы.
Home.spec.js
JavaScript
xxxxxxxxxx
1
import { shallowMount } from "@vue/test-utils";
2
import MyComponent from "@/MyComponent";
3
jest.mock("@/store/models/Post");
4
describe("MyComponent.vue", () => {
6
it("should render correctly", () => {
7
wrapper = shallowMount(MyComponent);
8
expect(wrapper).toMatchSnapshot();
9
});
10
});
При выполнении этого теста снова, Jest обеспечит график зависимости модифицирован , чтобы заменить "@/store/models/Post"
с издеваться вы создали, и вместо TypeError
, вы получите зеленый клещ.