Библиотека MUI (Material-UI) предоставляет готовые компоненты интерфейса на React, но для обеспечения качества приложения необходима полноценная проверка их работы через Testing Library. Testing Library ориентирована на тестирование компонентов так, как их воспринимает пользователь, а не на реализацию внутренней логики. Это особенно важно при работе с MUI, где компоненты часто оборачиваются в сложные контейнеры и используют стилизации и контексты.
Для корректного тестирования компонентов MUI требуется подключение следующих пакетов:
npm install @testing-library/react @testing-library/jest-dom @testing-library/user-event
@testing-library/react — основной пакет для рендеринга
компонентов.@testing-library/jest-dom — расширяет Jest матчерами
для удобной проверки DOM.@testing-library/user-event — имитация действий
пользователя (клики, ввод текста и т.д.).Если используется MUI v5, важно оборачивать
тестируемые компоненты в ThemeProvider, чтобы корректно
применялись темы:
import { ThemeProvider, createTheme } from '@mui/material/styles';
import { render } from '@testing-library/react';
import MyComponent from './MyComponent';
const theme = createTheme();
const renderWithTheme = (ui) =>
render(<ThemeProvider theme={theme}>{ui}</ThemeProvider>);
Для кнопок MUI (Button) ключевым является тестирование
действий пользователя через userEvent:
import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
test('кнопка вызывает функцию при клике', async () => {
const handleClick = jest.fn();
renderWithTheme(<Button onCl ick={handleClick}>Нажми меня</Button>);
const button = screen.getByRole('button', { name: /нажми меня/i });
await userEvent.click(button);
expect(handleClick).toHaveBeenCalledTimes(1);
});
Особенности MUI: визуальные стили и иконки не влияют на функциональность, поэтому проверка по роли и тексту предпочтительнее.
MUI предоставляет компоненты TextField,
Select, Checkbox и др., которые оборачивают
стандартные элементы HTML. Для TextField важно использовать
getByLabelText или getByRole:
test('текстовое поле обновляет значение', async () => {
renderWithTheme(<TextField label="Имя" />);
const input = screen.getByLabelText(/имя/i);
await userEvent.type(input, 'Алексей');
expect(input).toHaveValue('Алексей');
});
Для Select и Autocomplete проверка требует
имитации раскрытия списка и выбора элемента:
test('sel ect позволяет выбрать элемент', async () => {
renderWithTheme(
<Sel ect label="Фрукты" defaultValue="">
<MenuItem value="apple">Яблоко</MenuItem>
<MenuItem value="orange">Апельсин</MenuItem>
</Select>
);
const select = screen.getByLabelText(/фрукты/i);
await userEvent.click(select);
const option = screen.getByRole('option', { name: /апельсин/i });
await userEvent.click(option);
expect(select).toHaveTextContent(/апельсин/i);
});
MUI часто использует ThemeProvider, CssBaseline, LocalizationProvider (для компонентов DatePicker и TimePicker). В тестах их необходимо учитывать, иначе могут возникнуть ошибки при рендеринге:
import AdapterDateFns fr om '@mui/lab/AdapterDateFns';
import { LocalizationProvider } fr om '@mui/lab';
const renderWithProviders = (ui) =>
render(
<ThemeProvider theme={theme}>
<LocalizationProvider dateAdapter={AdapterDateFns}>
{ui}
</LocalizationProvider>
</ThemeProvider>
);
MUI компоненты меняют классы и атрибуты при интеракциях (hover, focus, disabled). Testing Library позволяет проверять это через Jest-DOM:
test('кнопка отключена при условии', () => {
renderWithTheme(<Button disabled>Отправить</Button>);
const button = screen.getByRole('button', { name: /отправить/i });
expect(button).toBeDisabled();
});
Для проверки видимости всплывающих элементов, таких как
Tooltip:
test('tooltip отображается при наведении', async () => {
renderWithTheme(<Tooltip title="Подсказка"><Button>Наведи</Button></Tooltip>);
const button = screen.getByRole('button', { name: /наведи/i });
await userEvent.hover(button);
const tooltip = await screen.findByText(/подсказка/i);
expect(tooltip).toBeVisible();
});
MUI использует анимации при открытии меню, диалогов и списков.
Testing Library предоставляет методы findBy* и
waitFor для корректной работы с асинхронными
элементами:
test('диалог открывается по кнопке', async () => {
renderWithTheme(
<>
<Button onCl ick={() => setOpen(true)}>Открыть</Button>
<Dialog open={open}><DialogTitle>Заголовок</DialogTitle></Dialog>
</>
);
await userEvent.click(screen.getByRole('button', { name: /открыть/i }));
const dialogTitle = await screen.findByText(/заголовок/i);
expect(dialogTitle).toBeInTheDocument();
});
getByRole, getByLabelText) вместо поиска по
классу или id. MUI генерирует динамические классы, которые
нестабильны.userEvent
вместо fireEvent, чтобы имитировать реальные действия
пользователя.Интеграция Testing Library с MUI позволяет писать надежные и поддерживаемые тесты, фокусируясь на поведении интерфейса, а не на внутренней реализации компонентов. Такой подход обеспечивает высокое качество и предсказуемость работы приложения при изменении версий MUI или стилевых компонентов.