Mocha и Chai с Enzyme

Mocha и Chai — популярные инструменты для тестирования в экосистеме JavaScript. Mocha — это тестовый фреймворк, который управляет запуском тестов и предоставляет инфраструктуру для их организации. Chai — это библиотека для утверждений, используемая для проверки результатов тестов. В сочетании с Enzyme они образуют мощную связку для тестирования React-компонентов, обеспечивая удобные методы для рендеринга компонентов, взаимодействия с ними и проверки их поведения.

Установка Mocha, Chai и Enzyme

Для начала необходимо установить все необходимые зависимости в проект.

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 и Chai

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

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 для утверждений

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 предлагает различные методы рендеринга и взаимодействия с компонентами. Это позволяет писать удобные и эффективные тесты, которые проверяют как визуальные аспекты компонентов, так и их внутреннее состояние и поведение.