Тестирование компонентов React с состоянием может быть немного сложнее, чем тестирование компонентов без состояния, но Jest и React Testing Library предоставляют мощные инструменты для этой задачи. Вот как вы можете тестировать компоненты с состоянием:

1. Импорт необходимых библиотек:

Для тестирования компонентов React с состоянием вам понадобятся следующие библиотеки:

  • Jest: Фреймворк для тестирования.
  • React Testing Library: Утилита для тестирования компонентов React.
  • @testing-library/react: Основная библиотека для тестирования React-компонентов.
  • @testing-library/user-event: Библиотека для имитации пользовательских событий.

2. Создание компонента с состоянием:

Предположим, у вас есть компонент Counter, который имеет состояние и две кнопки для увеличения и уменьшения счетчика.

import React, { useState } from 'react';
 
const Counter = () => {
  const [count, setCount] = useState(0);
 
  const increment = () => setCount(count + 1);
  const decrement = () => setCount(count - 1);
 
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
};
 
export default Counter;

3. Написание тестов для компонента с состоянием:

Теперь напишем тесты для компонента Counter, чтобы убедиться, что состояние изменяется правильно при нажатии на кнопки.

import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';
 
test('renders initial count', () => {
  render(<Counter />);
  const countElement = screen.getByText(/Count: 0/i);
  expect(countElement).toBeInTheDocument();
});
 
test('increments count when increment button is clicked', () => {
  render(<Counter />);
  const incrementButton = screen.getByText(/Increment/i);
  fireEvent.click(incrementButton);
  const countElement = screen.getByText(/Count: 1/i);
  expect(countElement).toBeInTheDocument();
});
 
test('decrements count when decrement button is clicked', () => {
  render(<Counter />);
  const decrementButton = screen.getByText(/Decrement/i);
  fireEvent.click(decrementButton);
  const countElement = screen.getByText(/Count: -1/i);
  expect(countElement).toBeInTheDocument();
});

4. Тестирование асинхронных изменений состояния:

Если ваш компонент имеет асинхронные изменения состояния, вы можете использовать waitFor для ожидания изменений.

import React, { useState, useEffect } from 'react';
 
const AsyncCounter = () => {
  const [count, setCount] = useState(0);
 
  useEffect(() => {
    const timer = setTimeout(() => setCount(count + 1), 1000);
    return () => clearTimeout(timer);
  }, [count]);
 
  return (
    <div>
      <p>Count: {count}</p>
    </div>
  );
};
 
export default AsyncCounter;

Пример тестового файла AsyncCounter.test.js:

import { render, screen, waitFor } from '@testing-library/react';
import AsyncCounter from './AsyncCounter';
 
test('renders initial count and increments after 1 second', async () => {
  render(<AsyncCounter />);
  const countElement = screen.getByText(/Count: 0/i);
  expect(countElement).toBeInTheDocument();
 
  await waitFor(() => {
    const updatedCountElement = screen.getByText(/Count: 1/i);
    expect(updatedCountElement).toBeInTheDocument();
  }, { timeout: 2000 });
});

Назад