Integration тесты (интеграционные тесты) проверяют корректное взаимодействие нескольких компонентов или модулей приложения, включая UI-библиотеки, такие как MUI (Material-UI). В отличие от unit-тестов, которые изолируют отдельный компонент, интеграционные тесты оценивают поведение компонентов в реальном контексте приложения: рендеринг, обработку событий и взаимодействие с состоянием.
В MUI важную роль играют компоненты с внутренней
логикой, такие как Autocomplete,
DatePicker, Drawer или DataGrid.
Эти компоненты требуют тестирования их интеграции с состоянием
приложения и внешними библиотеками (например,
react-hook-form или formik).
Для интеграционных тестов с MUI чаще всего используют комбинацию:
@testing-library/react — для рендеринга компонентов и
симуляции действий пользователя.jest — как тестовый раннер и фреймворк для
утверждений.msw (Mock Service Worker) — для мокирования
API-запросов, если компоненты взаимодействуют с сервером.Пример базовой настройки:
import { render, screen, fireEvent } from '@testing-library/react';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import MyComponent from './MyComponent';
const theme = createTheme();
const renderWithTheme = (ui) => {
return render(<ThemeProvider theme={theme}>{ui}</ThemeProvider>);
};
Важно: MUI-компоненты зависят от темы, поэтому
интеграционные тесты должны оборачивать компоненты в
ThemeProvider. Без этого некоторые стили и поведение могут
работать некорректно.
Button с событиемimport { Button } from '@mui/material';
test('клик по кнопке вызывает функцию', () => {
const handleClick = jest.fn();
renderWithTheme(<Button onCl ick={handleClick}>Нажми меня</Button>);
fireEvent.click(screen.getByText('Нажми меня'));
expect(handleClick).toHaveBeenCalledTimes(1);
});
Ключевые моменты:
fireEvent для симуляции пользовательских
действий.Autocompleteimport { Autocomplete, TextField } from '@mui/material';
const options = ['Москва', 'Санкт-Петербург', 'Казань'];
test('выбор элемента в Autocomplete', () => {
renderWithTheme(
<Autocomplete
options={options}
renderInput={(params) => <TextField {...params} label="Город" />}
/>
);
const input = screen.getByLabelText('Город');
fireEvent.change(input, { target: { value: 'Мо' } });
fireEvent.click(screen.getByText('Москва'));
expect(input.value).toBe('Москва');
});
Особенности интеграционного теста для Autocomplete:
MUI-компоненты часто используют Lazy-loading, API-запросы или debounce. В таких случаях интеграционные тесты должны учитывать асинхронность.
import { waitFor } from '@testing-library/react';
import { fetchData } from './api';
jest.mock('./api');
test('DataGrid отображает данные после загрузки', async () => {
fetchData.mockResolvedValue([{ id: 1, name: 'Item 1' }]);
renderWithTheme(<MyDataGridComponent />);
await waitFor(() => {
expect(screen.getByText('Item 1')).toBeInTheDocument();
});
});
Особенности:
waitFor для ожидания обновления DOM.Комбинация MUI и react-hook-form или formik
требует проверки интеграции поля ввода ↔︎ форма ↔︎
валидация.
import { TextField, Button } from '@mui/material';
import { useForm, Controller } from 'react-hook-form';
test('форма с TextField корректно валидирует', async () => {
const onSub mit = jest.fn();
renderWithTheme(
<Form onSub mit={onSubmit}>
<Controller
name="email"
control={control}
rules={{ required: 'Обязательное поле' }}
render={({ field }) => <TextField {...field} label="Email" />}
/>
<Button type="submit">Отправить</Button>
</Form>
);
fireEvent.click(screen.getByText('Отправить'));
await waitFor(() => {
expect(screen.getByText('Обязательное поле')).toBeInTheDocument();
});
});
Особенности:
onSubmit.msw или jest.mock.waitFor для корректной проверки DOM.getByRole и
getByLabelText для стабильности и соответствия ARIA.open и
close работают корректно, кнопки внутри модального окна
вызывают соответствующие функции.Интеграционные тесты в MUI позволяют гарантировать надежность приложения, проверяя не только отдельные компоненты, но и их совместную работу в реальных сценариях. Такой подход уменьшает риск ошибок при обновлении UI-библиотеки или бизнес-логики.