DRY (Don’t Repeat Yourself) — фундаментальный принцип разработки, направленный на минимизацию повторения кода. В контексте тестирования Vue-компонентов применение DRY позволяет создавать поддерживаемые, читаемые и масштабируемые тесты, сокращая дублирование логики и конфигураций.
Vue Test Utils предоставляет инструменты для монтирования компонентов
(mount, shallowMount) и взаимодействия с ними.
Повторяющиеся конфигурации компонентов можно вынести в отдельные
функции:
import { mount } from '@vue/test-utils';
import MyComponent from '@/components/MyComponent.vue';
function createWrapper(props = {}, options = {}) {
return mount(MyComponent, {
props,
...options
});
}
Такой подход позволяет:
Для сложных компонентов с множеством зависимостей целесообразно создавать фабрики данных и утилиты:
export function mockUser(overrides = {}) {
return {
id: 1,
name: 'John Doe',
role: 'admin',
...overrides
};
}
export function mountWithUser(props = {}) {
return mount(MyComponent, {
props: {
user: mockUser(),
...props
}
});
}
Такой подход облегчает:
Повторяющиеся действия, такие как клик по кнопке, ввод текста, проверка вывода, удобно оформлять как функции:
export function clickButton(wrapper, selector) {
const button = wrapper.find(selector);
button.trigger('click');
}
export function setInputValue(wrapper, selector, value) {
const input = wrapper.find(selector);
input.setValue(value);
}
Использование таких функций позволяет:
Для проверки одного сценария с различными наборами данных эффективна
параметризация через test.each или циклы:
const roles = ['admin', 'editor', 'guest'];
roles.forEach(role => {
test(`отображение кнопки для роли ${role}`, () => {
const wrapper = mountWithUser({ role });
expect(wrapper.find('button').exists()).toBe(role === 'admin');
});
});
Преимущества:
Vue Test Utils позволяет задавать глобальные конфигурации для всех
тестов через global:
import { config } from '@vue/test-utils';
config.global.stubs = ['router-link', 'font-awesome-icon'];
config.global.mocks = {
$t: (msg) => msg
};
Это позволяет:
const errorScenarios = [
{ field: 'email', message: 'Invalid email' },
{ field: 'password', message: 'Too short' }
];
errorScenarios.forEach(({ field, message }) => {
test(`отображает ошибку для поля ${field}`, async () => {
const wrapper = createWrapper();
await setInputValue(wrapper, `input[name="${field}"]`, '');
clickButton(wrapper, 'button.submit');
expect(wrapper.text()).toContain(message);
});
});
beforeEach(() => {
jest.clearAllMocks();
});
const wrapper = createWrapper({}, {
global: {
mocks: {
$store: { dispatch: jest.fn() }
}
}
});
В таких подходах минимизация повторения достигается через:
Такой подход обеспечивает гибкость, поддержку больших проектов и снижает затраты на изменение тестов при развитии приложения.