Имитация композируемых модулей, хранилищ и API
vi.mock(), имитация useFetch, хранилищ Pinia и маршрутизатора в тестах
«Имитация композируемых модулей, хранилищ и API» — бесплатный урок Vue Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Vue Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Vue Academy содержит 4 уроков всего.
Зачем нужны моки
Модульные тесты должны изолировать тестируемый компонент. Реальные сетевые запросы, настоящие хранилища и тяжёлые композаблы делают тесты медленными и нестабильными. Мокирование заменяет эти зависимости управляемыми подставными реализациями.
vi.fn: функция-мок
vi.fn() создаёт отслеживаемую функцию. Вы можете проверить, как она была вызвана, и управлять возвращаемым ею значением. Это основа любого мокирования.
import { vi } from "vitest"
const onSave = vi.fn()
onSave("draft")
expect(onSave).toHaveBeenCalledWith("draft")
expect(onSave).toHaveBeenCalledTimes(1)Настройка возвращаемых значений
Управляйте результатом имитируемой функции с помощью mockReturnValue (синхронный код) или mockResolvedValue (разрешённое обещание) для асинхронного кода.
const getId = vi.fn().mockReturnValue(42)
expect(getId()).toBe(42)
const fetchUser = vi.fn().mockResolvedValue({ name: "Ada" })
// await fetchUser() => { name: "Ada" }Мокирование модуля-композабла
vi.mock(path) заменяет целый модуль. Передайте фабрику, возвращающую подставные экспортируемые значения. Используйте её, чтобы заменить композабл заглушкой и передать компоненту предсказуемые данные.
import { vi } from "vitest"
vi.mock("@/composables/useUser", () => ({
useUser: () => ({
user: { value: { name: "Ada" } },
isLoading: { value: false },
}),
}))Поднятие vi.mock
Вызовы vi.mock поднимаются в начало файла до выполнения импортов. Поэтому фабрика не может обращаться к внешним переменным, объявленным позже: объявите вспомогательные элементы внутри фабрики или с помощью vi.hoisted.
// This runs before imports regardless of position.
vi.mock("@/api", () => ({ getPosts: vi.fn() }))
import { getPosts } from "@/api" // already the mockТестирование хранилищ Pinia
Компонентам, использующим хранилище Pinia, нужно хранилище в тестах. @pinia/testing предоставляет createTestingPinia, создающий хранилище, действия которого по умолчанию заменены заглушками.
// terminal: npm install -D @pinia/testing
import { createTestingPinia } from "@pinia/testing"Подключение тестового хранилища Pinia
Передайте тестовое хранилище Pinia через глобальную опцию plugins при монтировании. Вы также можете задать начальное состояние.
import { mount } from "@vue/test-utils"
import { createTestingPinia } from "@pinia/testing"
const wrapper = mount(Profile, {
global: {
plugins: [createTestingPinia({
initialState: { user: { name: "Ada" } },
})],
},
})Проверка действий хранилища
По умолчанию действия заменяются заглушками и не выполняются, поэтому вы можете проверить, что они были вызваны. Получите хранилище и проверьте шпион.
import { useUserStore } from "@/stores/user"
const store = useUserStore()
await wrapper.get("button.logout").trigger("click")
expect(store.logout).toHaveBeenCalled()Наблюдение за запросами
Вместо замены целого модуля можно наблюдать за глобальным объектом. vi.spyOn(global, "fetch") оборачивает настоящую функцию получения данных, чтобы вы могли переопределять её и проверять её вызовы.
const spy = vi.spyOn(global, "fetch").mockResolvedValue({
ok: true,
json: async () => ({ items: [1, 2, 3] }),
})Полный тест получения данных
Имитируйте получение данных, вызовите действие, дождитесь разрешения обещаний, проверьте отображаемые данные и убедитесь, что запрос был выполнен с правильным URL.
it("loads items", async () => {
vi.spyOn(global, "fetch").mockResolvedValue({
ok: true,
json: async () => ({ items: ["a", "b"] }),
})
const wrapper = mount(List)
await flushPromises()
expect(global.fetch).toHaveBeenCalledWith("/api/items")
expect(wrapper.findAll("li")).toHaveLength(2)
})Сброс моков между тестами
Общие моки накапливают историю вызовов. Сбрасывайте их в beforeEach (или включите clearMocks в конфигурации), чтобы один тест не влиял на другой.
import { beforeEach, vi } from "vitest"
beforeEach(() => {
vi.clearAllMocks()
})Быстрая проверка
Проверьте, насколько хорошо вы поняли мокирование.
Повторение
Вы научились заменять зависимости моками в тестах:
vi.fn()создаёт отслеживаемые функции; управляйте результатом с помощьюmockReturnValue/mockResolvedValue.vi.mock(path, factory)заменяет модуль (например, композабл); его вызов поднимается выше импортов.createTestingPiniaиз@pinia/testingпредоставляет хранилище с действиями-заглушками, вызовы которых можно проверять.vi.spyOn(global, "fetch").mockResolvedValue(...)имитирует сетевые запросы.- Сбрасывайте моки между тестами с помощью
vi.clearAllMocks().
Изучай HTML с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 42
- Уроки
- 156
Часто задаваемые вопросы
Урок «Имитация композируемых модулей, хранилищ и API» бесплатный?
Да — полный текст урока «Имитация композируемых модулей, хранилищ и API» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Vue Academy, подпишись на CoddyKit PRO. Курс Vue Academy содержит 4 уроков всего.
Чему я научусь в уроке «Имитация композируемых модулей, хранилищ и API»?
vi.mock(), имитация useFetch, хранилищ Pinia и маршрутизатора в тестах Ты практикуешь Vue Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Vue Academy?
Предыдущий опыт не требуется. Vue Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Имитация композируемых модулей, хранилищ и API»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Vue Academy?
Да. Каждый урок Vue Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Настройка Vitest для проектов Vue
- Монтирование и поиск компонентов
- Тестирование взаимодействий пользователя и событий
- Имитация композируемых модулей, хранилищ и API