Это руководство было написано для Vue.js 2 и Vue Test Utils v1.
Версия для Vue.js 3 здесь.
# Поиск элементов
vue-test-utils
даёт возможность находить и проверять html элементы или другие Vue компоненты разными способами, используя метод find
и findComponent
. Основной задачей find
является проверка, что компонент правильно отрисовывает элемент или дочерний компонент.
Заметка: Если вы использовали Vue Test Utils до v1, вы, возможно, помните, что
find
одновременно работал и с компонентами и с DOM элементами. Теперь вы должны использоватьfind
иfindAll
для DOM элементов, аfindComponent
иfindAllComponents
для Vue компонентов. Есть также методget
в паре сgetComponent
, которые работают идентичноfind
иfindComponent
, но они выбрасывают ошибку, если ничего не найдут. В этом руководстве используются методыfind
иfindComponent
.
Исходный код для теста на этой странице можно найти здесь.
# Создание компонентов
Для этого примера, мы создадим компоненты <Child>
и <Parent>
.
Child
:
<template>
<div>Дочерний компонент</div>
</template>
<script>
export default {
name: "Child"
}
</script>
Parent
:
<template>
<div>
<span v-show="showSpan">
Родительский компонент
</span>
<Child v-if="showChild" />
</div>
</template>
<script>
import Child from "./Child.vue"
export default {
name: "Parent",
components: { Child },
data() {
return {
showSpan: false,
showChild: false
}
}
}
</script>
# Синтаксис find
и querySelector
Обычные элементы можно легко найти, используя синтаксис похожий на document.querySelector
. vue-test-utils
также предоставляет метод isVisible
, чтобы проверять отрисовался ли элемент по условию с v-show
. Создадим Parent.spec.js
и внутрь добавим следующий тест:
import { mount } from "@vue/test-utils"
import '@testing-library/jest-dom'
import Parent from "@/components/Parent.vue"
describe("Parent.vue", () => {
it("Не отрисовывает span", () => {
const wrapper = mount(Parent)
expect(wrapper.find("span").element).not.toBeVisible()
})
})
Так как v-show="showSpan"
по умолчанию в значении false
, мы предполагаем, что найденный <span>
элемент не виден. Мы используем потрясающие матчеры из @testing-library/jest-dom
для проверки этого поведения. Определение видимости элемента – дело не простое, поэтому Vue Test Utils оставляет его для другой библиотеки. При запуске yarn test:unit
, тесты проходят проверку. Теперь нужно протестировать случай, когда showSpan
в значении true
.
it("Отрисовывает span", () => {
const wrapper = mount(Parent, {
data() {
return { showSpan: true }
}
})
expect(wrapper.find("span").element).toBeVisible()
})
Это работает!
# Поиск компонентов через name
и Component
Поиск дочерних компонентов немного отличается от поиска обычных HTML элементов. Есть два основных способа проверить наличие дочерних компонентов:
findComponent(Component)
findComponent({ name: "ComponentName" })
Это будет проще понять на примере. Давайте разберём синтаксис findComponent(Component)
. Нам нужно импортировать компонент через import
и передать его в функцию findComponent
.
import Child from "@/components/Child.vue"
it("не отрисовывает компонент Child", () => {
const wrapper = mount(Parent)
expect(wrapper.findComponent(Child).exists()).toBe(false)
})
Реализация метода find
и findComponent
довольно сложная, так как он работает с синтаксисом querySelector
и некоторыми другими. Здесь вы можете посмотреть на часть исходного кода, в котором ищутся дочерние компоненты. В основном, там проверяется name
всех отрисованных компонентов, а затем проверяется constructor
и некоторые другие свойства.
Как говорилось в предыдущем абзаце, когда вы передаёте компонент в find
, выполняется проверка свойства name
.
Вместо того чтобы передавать компонент, вы можете просто передать объект с правильным свойством name
. Это значит, что вам не нужно использовать import
для компонента. Давайте протестируем случай, когда <Child>
должен отрисовываться:
it("отрисовывает компонент Child", () => {
const wrapper = mount(Parent, {
data() {
return { showChild: true }
}
})
expect(wrapper.findComponent({ name: "Child" }).exists()).toBe(true)
})
Это работает! Использовать свойство name
, может быть, немного не интуитивно, поэтому, как альтернативу, можно импортировать компонент. Также можно просто добавить class
или id
, а затем найти элемент синтаксисом querySelector
, как в первых двух примерах.
# findAll
и findAllComponents
Часто бывают случаи, когда вы хотите проверить количество отрисованных элементов. Обычно, список элементов отрисовывается через v-for
. Вот компонент <ParentWithManyChildren>
, который отрисовывает несколько компонентов <Child>
.
<template>
<div>
<Child v-for="id in [1, 2 ,3]" :key="id" />
</div>
</template>
<script>
import Child from "./Child.vue"
export default {
name: "ParentWithManyChildren",
components: { Child }
}
</script>
Вот так мы можем написать тест, используя findAllComponents
для проверки отрисовки трёх компонентов <Child>
:
it("отрисовывает несколько дочерних компонентов", () => {
const wrapper = shallowMount(ParentWithManyChildren)
expect(wrapper.findAllComponents(Child).length).toBe(3)
})
Запуск yarn test:unit
показывает, что тест проходит проверку. Вы также можете использовать querySelector
с синтаксисом findAll
.
# Заключение
На этой странице рассматривалось, как:
- использовать
find
иfindAll
с синтаксисом похожим наquerySelector
- использовать
findComponent
иfindAllComponents
для поиска Vue компонентов - использовать
exists
для проверки существования чего-либо,toBeVisible
из@testing-library/jest-dom
для проверки элементов, которые существуют, но не видимы
Исходный код для теста на этой странице можно найти здесь.