Vue Test Utils: тестирование компонентов
↑ 4.1 Vue 3: основы, компоненты, Composition API · ← Предыдущая · → Следующая
Зачем это на собесе
Практика тестирования компонентов: монтирование, props, события, слоты и изоляция.
Объяснение
Vue Test Utils (VTU) — официальная библиотека для монтирования компонентов в тестах (с Vitest).
import { mount, shallowMount, flushPromises } from "@vue/test-utils";
import { describe, it, expect, vi } from "vitest";
import OrderCard from "./OrderCard.vue";
describe("OrderCard", () => {
const factory = (props = {}) => mount(OrderCard, {
props: { order: { id: 1, number: "A-1", total: 100 }, ...props },
global: { plugins: [pinia, router], stubs: { RouterLink: true }, provide: { [ThemeKey as symbol]: theme } },
slots: { footer: "<em>подвал</em>" },
});
it("отображает номер и сумму", () => {
const w = factory();
expect(w.text()).toContain("A-1");
expect(w.find("[data-test=total]").text()).toBe("100,00 ₽");
});
it("эмитит save при клике", async () => {
const w = factory();
await w.get("button").trigger("click"); // trigger возвращает nextTick
expect(w.emitted("save")).toHaveLength(1);
expect(w.emitted("save")![0]).toEqual([{ id: 1 }]);
});
it("обновляется при смене props", async () => {
const w = factory();
await w.setProps({ order: { id: 1, number: "B-2", total: 5 } });
expect(w.text()).toContain("B-2");
});
it("v-model на input", async () => {
const w = factory();
await w.get("input").setValue("abc");
expect(w.emitted("update:modelValue")![0]).toEqual(["abc"]);
});
});| API | Назначение |
|---|---|
mount | полный рендер с дочерними компонентами |
shallowMount | дочерние компоненты заменены заглушками |
find/get/findAll/findComponent | поиск элементов/компонентов (get бросает ошибку при отсутствии) |
trigger, setValue, setProps | взаимодействие |
emitted() | записанные события |
wrapper.vm | экземпляр (лучше не использовать) |
global.* | плагины, stubs, mocks, provide, directives |
flushPromises | дождаться промисов |
attachTo: document.body | монтирование в реальный DOM (фокус, layout) |
Что тестировать: публичный интерфейс — props → отображение, действия пользователя → emits/побочные эффекты, слоты. Не тестируйте внутреннее состояние и приватные методы.
Стабильные селекторы: data-test/data-testid атрибуты.
Нюансы и подводные камни
- Не забывайте
awaitпослеtrigger/setValue/setProps. shallowMountскрывает интеграцию — используйте осознанно.wrapper.vm.xзавязывает тест на реализацию.- Асинхронные компоненты/Suspense требуют
flushPromises/обёртки. - Проверка структуры DOM через снапшоты — хрупкая.
Практика
- Покройте компонент таблицы тестами: рендер, сортировка, события, слоты.
- Подключите Pinia и Router через
global.plugins. - Замените
wrapper.vmна проверки через DOM и emits.
Вопросы с ответами
mountилиshallowMount?
mountрендерит дерево целиком (ближе к реальности),shallowMountподменяет дочерние компоненты заглушками для изоляции.
Что тестировать в компоненте?
Наблюдаемое поведение: рендер по props, реакция на действия, события и слоты.