Для unit-тестирования компонентов Ant Design в JavaScript чаще всего используется комбинация Jest и React Testing Library. Jest обеспечивает быстрый и изолированный запуск тестов, а React Testing Library позволяет работать с компонентами так, как это делает пользователь, ориентируясь на их рендер и события.
Установка необходимых пакетов:
npm install --save-dev jest @testing-library/react @testing-library/jest-dom
Также рекомендуется подключить babel-jest, если используется Babel для трансформации JSX.
npm install --save-dev babel-jest @babel/preset-env @babel/preset-react
Настройка jest.config.js:
module.exports = {
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
transform: {
'^.+\\.(js|jsx)$': 'babel-jest',
},
};
Компоненты Ant Design, такие как Button,
поддерживают различные типы и состояния (type,
loading, disabled). Проверка их поведения
заключается в рендере компонента и симуляции действий пользователя.
Пример теста кнопки:
import { render, screen, fireEvent } from '@testing-library/react';
import { Button } from 'antd';
test('Button вызывает onClick', () => {
const handleClick = jest.fn();
render(<Button onCl ick={handleClick}>Нажми меня</Button>);
const button = screen.getByText('Нажми меня');
fireEvent.click(button);
expect(handleClick).toHaveBeenCalledTimes(1);
});
Ключевой момент: использовать screen.getByText
или screen.getByRole для поиска элементов, вместо
обращения напрямую к DOM.
Формы Ant Design (Form, Input,
Select, Checkbox) требуют особого подхода
из-за внутреннего состояния и валидации. React Testing Library позволяет
эмулировать ввод данных и проверять ошибки валидации.
Пример проверки формы с полем Input:
import { render, screen, fireEvent } from '@testing-library/react';
import { Form, Input, Button } from 'antd';
const MyForm = ({ onSubmit }) => (
<Form onFin ish={onSubmit}>
<Form.Item
name="username"
rules={[{ required: true, message: 'Введите имя пользователя' }]}
>
<Input placeholder="Имя пользователя" />
</Form.Item>
<Button htmlType="submit">Отправить</Button>
</Form>
);
test('Form показывает ошибку при пустом поле', async () => {
const handleSubmit = jest.fn();
render(<MyForm onSub mit={handleSubmit} />);
fireEvent.click(screen.getByText('Отправить'));
expect(await screen.findByText('Введите имя пользователя')).toBeInTheDocument();
expect(handleSubmit).not.toHaveBeenCalled();
});
Особенность Ant Design: ошибки валидации рендерятся
асинхронно, поэтому для их проверки используется
findByText, чтобы дождаться появления сообщения.
Компоненты типа Modal требуют проверки открывания и
закрывания, а также корректного вызова коллбеков (onOk,
onCancel).
Пример:
import { render, screen, fireEvent } from '@testing-library/react';
import { Modal, Button } from 'antd';
import { useState } from 'react';
const MyModal = ({ onOk }) => {
const [visible, setVisible] = useState(false);
return (
<>
<Button onCl ick={() => setVisible(true)}>Открыть модальное окно</Button>
<Modal
open={visible}
onOk={() => {
onOk();
setVisible(false);
}}
onCan cel={() => setVisible(false)}
>
Содержимое модального окна
</Modal>
</>
);
};
test('Modal вызывает onOk и закрывается', () => {
const handleOk = jest.fn();
render(<MyModal onOk={handleOk} />);
fireEvent.click(screen.getByText('Открыть модальное окно'));
fireEvent.click(screen.getByText('OK'));
expect(handleOk).toHaveBeenCalledTimes(1);
expect(screen.queryByText('Содержимое модального окна')).not.toBeInTheDocument();
});
Здесь важно использовать queryByText
для проверки отсутствия элемента после закрытия модального окна.
Для компонентов с нестандартной версткой или сложными стилями полезно snapshot-тестирование, чтобы отлавливать нежелательные визуальные изменения.
import { render } from '@testing-library/react';
import { Button } from 'antd';
test('Button рендерится корректно', () => {
const { asFragment } = render(<Button type="primary">Кнопка</Button>);
expect(asFragment()).toMatchSnapshot();
});
Преимущество: автоматическая фиксация структуры DOM. Важно: использовать для проверки структуры, а не функциональности.
Компонент Table часто содержит динамические данные, сортировку и пагинацию. Основные тесты включают проверку рендера данных и вызов обработчиков событий.
Пример теста сортировки:
import { render, screen, fireEvent } from '@testing-library/react';
import { Table } from 'antd';
const columns = [
{ title: 'Имя', dataIndex: 'name', key: 'name', sorter: (a, b) => a.name.localeCompare(b.name) },
];
const data = [
{ key: '1', name: 'Анна' },
{ key: '2', name: 'Борис' },
];
test('Table сортирует данные', () => {
render(<Table columns={columns} dataSource={data} />);
const header = screen.getByText('Имя');
fireEvent.click(header); // триггер сортировки
const rows = screen.getAllByRole('row');
expect(rows[1]).toHaveTextContent('Анна');
expect(rows[2]).toHaveTextContent('Борис');
});
Для таблиц рекомендуется тестировать функциональность, а не визуальное представление, так как Ant Design генерирует сложный DOM.
Компоненты Ant Design часто используются вместе с внешними
библиотеками, например moment для DatePicker или
axios для загрузки данных. Unit-тесты должны
изолировать компонент, поэтому внешние зависимости
мокаются.
Пример мока axios:
import axios from 'axios';
jest.mock('axios');
axios.get.mockResolvedValue({ data: [{ id: 1, name: 'Тест' }] });
screen для поиска
элементов: это делает тесты более читаемыми и похожими на
пользовательские сценарии.fireEvent или
userEvent для симуляции кликов, ввода и других
действий.findBy и waitFor для проверки появления
элементов, зависящих от состояния или валидации.Unit-тестирование компонентов Ant Design требует внимания к внутреннему состоянию и событиям, но при правильной настройке Jest и React Testing Library тесты становятся стабильными, читаемыми и поддерживаемыми.