Enzyme — это популярная библиотека для тестирования компонентов React, которая предоставляет API для рендеринга, поиска элементов, симуляции событий и проверки состояния компонентов. Для написания качественных тестов с использованием Enzyme необходимо понимать последовательность действий, которые позволяют выполнить тесты корректно. Рассмотрим поэтапное выполнение тестов с Enzyme, начиная с базовых концепций до более сложных случаев.
Для начала необходимо установить саму библиотеку Enzyme и несколько вспомогательных пакетов, которые обеспечат интеграцию с выбранным тестовым фреймворком, например, Jest.
npm install --save enzyme enzyme-adapter-react-16 jest
Затем следует настроить Enzyme для работы с React. Для этого создаётся файл конфигурации, в котором подключается адаптер для React:
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
Этот код гарантирует, что Enzyme будет правильно работать с React-компонентами и тестировать их.
Основной задачей при тестировании является рендеринг компонента и последующая проверка его работы. Enzyme предоставляет несколько методов рендеринга:
Пример рендеринга компонента с использованием метода
shallow:
import { shallow } from 'enzyme';
import MyComponent from './MyComponent';
describe('<MyComponent />', () => {
it('рендерится корректно', () => {
const wrapper = shallow(<MyComponent />);
expect(wrapper).toMatchSnapshot();
});
});
В данном примере используется метод toMatchSnapshot,
чтобы сравнить текущий вывод компонента с предыдущим снимком.
Один из важных аспектов тестирования — это симуляция пользовательских
событий, таких как клики, ввод текста, наведение мыши и другие. Enzyme
предоставляет функцию simulate, которая позволяет
симулировать события на выбранных элементах.
Пример симуляции клика на кнопке:
it('вызывает обработчик клика', () => {
const onCl ick = jest.fn();
const wrapper = shallow(<button onCl ick={onClick}>Click me</button>);
wrapper.simulate('click');
expect(onClick).toHaveBeenCalled();
});
Здесь создаётся фейковая функция onClick, которая
проверяется на вызов после симуляции клика.
Enzyme позволяет тестировать компоненты, у которых есть состояние.
Для этого используется метод .state(), который позволяет
получить текущее состояние компонента.
Пример проверки состояния компонента:
it('меняет состояние при клике', () => {
const wrapper = shallow(<MyComponent />);
expect(wrapper.state().isClicked).toBe(false);
wrapper.find('button').simulate('click');
expect(wrapper.state().isClicked).toBe(true);
});
В данном примере проверяется, что состояние компонента изменяется после клика на кнопку.
Пропсы компонентов могут изменяться в процессе их рендеринга. Для их
проверки используется метод .props(), который позволяет
извлечь все пропсы компонента.
Пример проверки пропсов компонента:
it('получает правильный пропс', () => {
const wrapper = shallow(<MyComponent name="John" />);
expect(wrapper.props().name).toBe('John');
});
Здесь проверяется, что переданный пропс name имеет
значение “John”.
Часто возникает необходимость замены реальных функций или API на моки, чтобы тесты не зависели от внешних факторов. Jest предоставляет возможность создания мок-функций, которые могут быть использованы в тестах.
Пример мокирования API:
it('вызывает API', () => {
const apiMock = jest.fn().mockReturnValue(Promise.resolve('response'));
const wrapper = shallow(<MyComponent fetchData={apiMock} />);
wrapper.instance().fetchData();
expect(apiMock).toHaveBeenCalled();
});
В данном случае мокируется функция API, и проверяется, что она была вызвана.
Для тестирования асинхронных операций, таких как запросы к серверу
или отложенные действия, необходимо использовать асинхронные методы
Jest. Enzyme позволяет тестировать компоненты с асинхронными операциями,
используя методы async/await.
Пример асинхронного теста:
it('загружает данные асинхронно', async () => {
const wrapper = shallow(<MyComponent />);
await wrapper.instance().fetchData();
wrapper.update();
expect(wrapper.state().data).toBe('response');
});
В этом примере данные загружаются асинхронно, и после завершения операции обновляется состояние компонента.
Снимки позволяют проверять, что визуальное представление компонента не изменяется со временем. Jest и Enzyme предлагают удобный способ работы с этим методом. Важно помнить, что снимки должны обновляться осознанно, чтобы не нарушить корректность тестов.
Пример использования снимков:
it('снимок компонента', () => {
const wrapper = shallow(<MyComponent />);
expect(wrapper).toMatchSnapshot();
});
Если компонент изменится, Jest предложит обновить снимок, чтобы отразить эти изменения.
mountМетод mount используется для рендеринга компонентов с их
дочерними элементами. Это полезно при тестировании сложных компонентов,
взаимодействующих с состоянием или жизненным циклом. Он позволяет делать
более точные проверки, чем поверхностный рендеринг.
Пример использования mount:
import { mount } from 'enzyme';
it('работает с состоянием в mount', () => {
const wrapper = mount(<MyComponent />);
expect(wrapper.find('button').prop('disabled')).toBe(true);
wrapper.setState({ isDisabled: false });
wrapper.update();
expect(wrapper.find('button').prop('disabled')).toBe(false);
});
Здесь компонент рендерится с полным состоянием, и проверяется, как изменяется его поведение при изменении состояния.
Важно помнить, что после каждого теста состояние компонентов и
глобальные объекты могут быть изменены. Для очистки используется метод
afterEach, который позволяет сбрасывать все изменения между
тестами.
Пример очистки:
afterEach(() => {
jest.clearAllMocks();
});
Этот метод очищает все моки и позволяет избежать “загрязнения” тестов между различными кейсами.
Для тестирования компонентов, использующих сторонние библиотеки или API, часто приходится мокировать их, чтобы избежать реальных запросов или изменений в окружении.
Пример мокирования библиотеки:
jest.mock('axios');
import axios from 'axios';
import MyComponent from './MyComponent';
it('обрабатывает успешный запрос', async () => {
axios.get.mockResolvedValue({ data: 'response' });
const wrapper = mount(<MyComponent />);
await wrapper.instance().fetchData();
expect(wrapper.state().data).toBe('response');
});
Здесь используется мока для библиотеки axios, что
позволяет тестировать компонент без реальных запросов.
Тестирование компонентов с помощью Enzyme включает в себя различные этапы: рендеринг, симуляция событий, проверка состояния и пропсов, а также работа с асинхронными функциями. Правильная последовательность действий и использование соответствующих методов позволяет создавать стабильные и качественные тесты для React-компонентов, обеспечивая их корректную работу на всех уровнях.