Для тестирования компонентов Vue, которые используют axios для HTTP-запросов, необходимо изолировать сетевое взаимодействие. Это позволяет проверять логику компонентов без реального обращения к серверу, предотвращая зависимость тестов от внешних API.
На практике чаще всего используется mocking axios с помощью Jest:
import { mount } from '@vue/test-utils';
import axios from 'axios';
import Component from '@/components/Component.vue';
jest.mock('axios');
После вызова jest.mock('axios') все методы axios
становятся Jest-моками, что позволяет управлять их поведением и
проверять вызовы.
Основной подход заключается в настройке возвращаемого значения
методов axios.get, axios.post и других:
axios.get.mockResolvedValue({
data: { message: 'Success' }
});
axios.post.mockRejectedValue(new Error('Network Error'));
Для более сложных сценариев можно использовать mockImplementation, чтобы реализовать динамическую логику:
axios.get.mockImplementation((url) => {
if (url === '/api/user') {
return Promise.resolve({ data: { id: 1, name: 'Alice' } });
}
return Promise.reject(new Error('Not Found'));
});
Компоненты, использующие axios, обычно вызывают его внутри методов
или хуков жизненного цикла, например mounted или
created.
Пример теста метода, который загружает данные при монтировании:
test('загружает данные при монтировании', async () => {
axios.get.mockResolvedValue({ data: { name: 'Vue' } });
const wrapper = mount(Component);
// Дожидаемся завершения всех асинхронных операций
await wrapper.vm.$nextTick();
expect(axios.get).toHaveBeenCalledWith('/api/data');
expect(wrapper.text()).toContain('Vue');
});
Ключевые моменты:
await wrapper.vm.$nextTick() или
flushPromises.toHaveBeenCalledWith.Компоненты должны корректно реагировать на ошибки сетевых запросов:
test('обрабатывает ошибки запроса', async () => {
axios.get.mockRejectedValue(new Error('Server Error'));
const wrapper = mount(Component);
await wrapper.vm.$nextTick();
expect(wrapper.text()).toContain('Ошибка загрузки данных');
});
Важно проверять не только факт вызова запроса, но и корректность отображения ошибок или fallback-контента в шаблоне.
Для ожидания завершения всех промисов можно подключить библиотеку
flush-promises:
import flushPromises from 'flush-promises';
test('корректно обрабатывает данные с сервера', async () => {
axios.get.mockResolvedValue({ data: { value: 42 } });
const wrapper = mount(Component);
await flushPromises();
expect(wrapper.vm.data.value).toBe(42);
expect(wrapper.text()).toContain('42');
});
flush-promises особенно полезен, когда в компоненте
несколько последовательных асинхронных вызовов.
Для крупных проектов удобнее создать глобальный mock axios, чтобы не дублировать настройку в каждом тесте:
// __mocks__/axios.js
export default {
get: jest.fn(),
post: jest.fn(),
put: jest.fn(),
delete: jest.fn()
};
Jest автоматически подхватывает этот файл при
jest.mock('axios'). Это обеспечивает единообразие моков и
упрощает поддержку тестов.
При использовании Vuex часто actions делают HTTP-запросы через axios. Тестирование таких actions включает мокацию axios и проверку мутаций:
import { actions } from '@/store/module';
import axios from 'axios';
jest.mock('axios');
test('action fetchUser коммитит мутацию с данными', async () => {
const commit = jest.fn();
axios.get.mockResolvedValue({ data: { id: 1, name: 'Alice' } });
await actions.fetchUser({ commit });
expect(commit).toHaveBeenCalledWith('SET_USER', { id: 1, name: 'Alice' });
});
Таким образом, тестирование действий Vuex с axios строится на мокации HTTP-запросов и проверке вызовов commit.
await wrapper.vm.$nextTick() или
flushPromises).Такой подход обеспечивает детальное покрытие компонентов и Vuex-модулей, использующих axios, без зависимости от внешних API и реальных сетевых условий.