Mocha и Chai — популярные инструменты для тестирования в экосистеме JavaScript. Mocha — это тестовый фреймворк, который управляет запуском тестов и предоставляет инфраструктуру для их организации. Chai — это библиотека для утверждений, используемая для проверки результатов тестов. В сочетании с Enzyme они образуют мощную связку для тестирования React-компонентов, обеспечивая удобные методы для рендеринга компонентов, взаимодействия с ними и проверки их поведения.
Для начала необходимо установить все необходимые зависимости в проект.
npm install --save-dev mocha chai enzyme enzyme-adapter-react-16 jsdom
Важной частью установки является конфигурация адаптера для Enzyme.
Для работы с React 16 или более поздними версиями необходимо
использовать enzyme-adapter-react-16.
Затем создайте файл настройки для Enzyme. Обычно это файл
setupTests.js в корне проекта:
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
После этого можно приступать к написанию тестов.
Mocha предоставляет функции describe и it
для организации тестов. describe группирует связанные
тесты, а it описывает конкретные проверки.
Пример базовой структуры теста:
describe('MyComponent', () => {
it('renders without crashing', () => {
const wrapper = shallow(<MyComponent />);
expect(wrapper.exists()).to.be.true;
});
});
Здесь:
describe('MyComponent', ...) — блок, в котором
группируются все тесты для компонента.it('renders without crashing', ...) — отдельный тест,
который проверяет рендер компонента.Enzyme предоставляет несколько методов для рендеринга компонентов:
shallow, mount, render. Выбор
метода зависит от целей теста.
shallow — поверхностный рендеринг компонента, при
котором дочерние компоненты не рендерятся, что ускоряет выполнение
тестов и изолирует компонент от внешнего контекста.mount — полный рендеринг компонента с полным деревом
компонентов и возможностью симуляции событий.render — генерирует только HTML-разметку, без создания
экземпляров React-компонентов.shallowМетод shallow полезен для изолированного тестирования
компонента. В этом примере тестируется компонент, который выводит текст
внутри <div>:
import React from 'react';
import { shallow } from 'enzyme';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
it('renders the correct text', () => {
const wrapper = shallow(<MyComponent />);
expect(wrapper.text()).to.equal('Hello, world!');
});
});
Здесь:
shallow(<MyComponent />) — создает поверхностный
рендер компонента.wrapper.text() — извлекает текстовое содержимое
компонента.expect(wrapper.text()).to.equal('Hello, world!') —
проверка, что текст соответствует ожидаемому значению.mountМетод mount используется, когда требуется полный
рендеринг компонента с учетом всех дочерних компонентов и контекста.
import React from 'react';
import { mount } from 'enzyme';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
it('correctly handles button click', () => {
const wrapper = mount(<MyComponent />);
wrapper.find('button').simulate('click');
expect(wrapper.state().clicked).to.be.true;
});
});
Здесь:
mount(<MyComponent />) — производит полный
рендеринг компонента.wrapper.find('button').simulate('click') — симулирует
клик по кнопке внутри компонента.wrapper.state().clicked — проверяет состояние
компонента после события.Chai предоставляет различные стилы утверждений, включая
expect, should и assert. Наиболее
распространённым является стиль expect, так как он наиболее
читаемый и интуитивно понятный.
Пример использования Chai с Mocha:
import { expect } from 'chai';
describe('Math operations', () => {
it('should add numbers correctly', () => {
const sum = 2 + 2;
expect(sum).to.equal(4);
});
it('should subtract numbers correctly', () => {
const diff = 5 - 3;
expect(diff).to.equal(2);
});
});
Enzyme позволяет легко проверять состояние компонента и его методы. Пример теста, который проверяет изменение состояния при клике на кнопку:
import React, { Component } from 'react';
import { mount } from 'enzyme';
class Counter extends Component {
state = { count: 0 };
increment = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>{this.state.count}</p>
<button onCl ick={this.increment}>Increment</button>
</div>
);
}
}
describe('Counter', () => {
it('increments the count on button click', () => {
const wrapper = mount(<Counter />);
wrapper.find('button').simulate('click');
expect(wrapper.state().count).to.equal(1);
});
});
В этом примере:
wrapper.state().count — проверяется состояние
компонента.wrapper.find('button').simulate('click') — симулируется
клик по кнопке, вызывающий изменение состояния.При тестировании компонентов, которые взаимодействуют с API или делают асинхронные запросы, можно использовать моки или заглушки.
Пример с использованием мока для тестирования асинхронного метода:
import React, { Component } from 'react';
import { mount } from 'enzyme';
import axios from 'axios';
jest.mock('axios');
class FetchData extends Component {
state = { data: null };
componentDidMount() {
axios.get('/data').then(response => {
this.setState({ data: response.data });
});
}
render() {
return <div>{this.state.data ? this.state.data : 'Loading...'}</div>;
}
}
describe('FetchData', () => {
it('fetches data on mount', async () => {
axios.get.mockResolvedValue({ data: 'test data' });
const wrapper = mount(<FetchData />);
await wrapper.instance().componentDidMount();
wrapper.update();
expect(wrapper.text()).to.equal('test data');
});
});
Здесь используется jest.mock для создания мока для
axios, а также асинхронная проверка с использованием
async/await.
Комбинация Mocha, Chai и Enzyme предоставляет мощные инструменты для тестирования React-компонентов. Mocha организует выполнение тестов, Chai предоставляет удобные утверждения для проверки состояния компонентов, а Enzyme предлагает различные методы рендеринга и взаимодействия с компонентами. Это позволяет писать удобные и эффективные тесты, которые проверяют как визуальные аспекты компонентов, так и их внутреннее состояние и поведение.