Для интеграции Chakra UI с библиотекой тестирования рекомендуется
использовать @testing-library/react. Это позволяет
рендерить компоненты Chakra UI в изолированном окружении и проверять их
поведение и визуальное состояние.
Установка необходимых пакетов:
npm install @testing-library/react @testing-library/jest-dom @testing-library/user-event
Для корректной работы компонентов Chakra UI важно оборачивать их в
ChakraProvider при тестировании. Это можно сделать с
помощью вспомогательной функции renderWithChakra:
import { render } from '@testing-library/react';
import { ChakraProvider } from '@chakra-ui/react';
export function renderWithChakra(ui, options) {
return render(<ChakraProvider>{ui}</ChakraProvider>, options);
}
Теперь все тесты, использующие эту функцию, будут корректно отображать стили и темы Chakra UI.
Button)Компоненты Button можно тестировать на наличие текста,
состояния disabled и реакции на события клика:
import { Button } from '@chakra-ui/react';
import { renderWithChakra } from './test-utils';
import userEvent from '@testing-library/user-event';
test('кнопка рендерится и реагирует на клик', async () => {
const handleClick = jest.fn();
const { getByText } = renderWithChakra(
<Button onCl ick={handleClick}>Нажми меня</Button>
);
const button = getByText('Нажми меня');
expect(button).toBeInTheDocument();
await userEvent.click(button);
expect(handleClick).toHaveBeenCalledTimes(1);
});
Ключевой момент — использование userEvent вместо
fireEvent для более реалистичного взаимодействия с
компонентом.
isDisabled, isLoading)test('кнопка с состоянием disabled', () => {
const { getByText } = renderWithChakra(
<Button isDisabled>Запрещено</Button>
);
const button = getByText('Запрещено');
expect(button).toBeDisabled();
});
test('кнопка с состоянием загрузки', () => {
const { getByRole } = renderWithChakra(
<Button isLoading>Загрузка</Button>
);
const button = getByRole('button');
expect(button).toHaveAttribute('aria-busy', 'true');
});
Input)Проверка ввода текста и состояния компонента:
import { Input } from '@chakra-ui/react';
test('поле ввода принимает текст', async () => {
const { getByPlaceholderText } = renderWithChakra(
<Input placeholder="Введите имя" />
);
const input = getByPlaceholderText('Введите имя');
await userEvent.type(input, 'Алексей');
expect(input).toHaveValue('Алексей');
});
Select)import { Sel ect } from '@chakra-ui/react';
test('выбор опции в Sel ect', async () => {
const { getByRole } = renderWithChakra(
<Select>
<option value="1">Опция 1</option>
<option value="2">Опция 2</option>
</Select>
);
const sel ect = getByRole('combobox');
await userEvent.selectOptions(select, '2');
expect(select.value).toBe('2');
});
Modal)Для тестирования Modal важно проверять открытие,
закрытие и содержимое. При этом модальные окна рендерятся в
Portal, поэтому может понадобиться использовать
container или document.body:
import { Modal, ModalOverlay, ModalContent, ModalBody, ModalCloseButton } fr om '@chakra-ui/react';
test('открытие и закрытие модального окна', async () => {
const { getByText, queryByText } = renderWithChakra(
<Modal isOpen onCl ose={() => {}}>
<ModalOverlay />
<ModalContent>
<ModalCloseButton />
<ModalBody>Содержимое модалки</ModalBody>
</ModalContent>
</Modal>
);
expect(getByText('Содержимое модалки')).toBeInTheDocument();
const closeButton = getByText('×');
await userEvent.click(closeButton);
// Если onClose не изменяет состояние, содержимое останется, но в реальных тестах состояние должно быть мокировано
});
Chakra UI поддерживает темы и цветовые режимы
(light/dark). Для проверки корректной работы
темы можно использовать контекст ChakraProvider с кастомной
темой:
import { extendTheme, Box } fr om '@chakra-ui/react';
const customTheme = extendTheme({
colors: {
brand: {
500: '#ff0000',
},
},
});
test('проверка кастомной темы', () => {
const { getByText } = render(
<ChakraProvider theme={customTheme}>
<Box color="brand.500">Текст брендового цвета</Box>
</ChakraProvider>
);
const box = getByText('Текст брендового цвета');
expect(box).toHaveStyle({ color: '#ff0000' });
});
Компоненты Chakra UI могут использовать framer-motion
для анимаций. Для юнит-тестов анимации часто отключают, чтобы тесты
оставались стабильными:
import { Collapse } fr om '@chakra-ui/react';
test('Collapse раскрывается', () => {
const { getByText } = renderWithChakra(
<Collapse in={true}>
<div>Контент</div>
</Collapse>
);
expect(getByText('Контент')).toBeVisible();
});
Использование in={true} гарантирует, что контент сразу
виден, без ожидания анимации.
theme,
colorMode, Portal), должны оборачиваться в
ChakraProvider.userEvent предпочтителен перед fireEvent
для имитации пользовательского взаимодействия.motion или использовать фиктивные
пропсы.@testing-library/jest-dom с матчерами
toHaveStyle, toBeVisible и
toHaveAttribute.Portal (Modal,
Popover, Drawer), требуют особого внимания к
контейнеру рендера и состоянию isOpen.Эти подходы обеспечивают стабильное, предсказуемое тестирование интерфейсов на базе Chakra UI с использованием Testing Library.