Это руководство было написано для Vue.js 3 и Vue Test Utils v2.
Версия для Vue.js 2 здесь.
# Поиск элементов
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 = mount(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для проверки элементов, которые существуют, но не видимы
Исходный код для теста на этой странице можно найти здесь.