Сортировка данных в таблицах

Сортировка данных в таблицах — это одна из наиболее распространённых и важных операций в современных веб-приложениях. В React-компонентах, которые часто используют таблицы для отображения данных, требуется возможность сортировать строки по различным столбцам. Это полезно не только для улучшения пользовательского опыта, но и для повышения эффективности взаимодействия с приложением. Важно обеспечить корректную работу таких операций, а также убедиться, что они правильно тестируются.

Структура таблицы с данными

Таблица, как правило, состоит из нескольких элементов: заголовков столбцов, строк с данными и, возможно, постраничной навигации. В простейшем случае она может быть представлена следующим образом:

const Table = ({ data, sortColumn, onSort }) => (
  <table>
    <thead>
      <tr>
        <th>
          <button onCl ick={() => onSort('name')}>Имя</button>
        </th>
        <th>
          <button onCl ick={() => onSort('age')}>Возраст</button>
        </th>
      </tr>
    </thead>
    <tbody>
      {data.map(item => (
        <tr key={item.id}>
          <td>{item.name}</td>
          <td>{item.age}</td>
        </tr>
      ))}
    </tbody>
  </table>
);

В данном примере таблица отображает данные о пользователях, включая их имя и возраст. Функция onSort отвечает за сортировку данных по столбцам.

Логика сортировки

Для реализации сортировки данных можно использовать несколько подходов. Рассмотрим пример на основе сортировки массива объектов по одному из полей.

const sortData = (data, column) => {
  return data.sort((a, b) => {
    if (a[column] < b[column]) return -1;
    if (a[column] > b[column]) return 1;
    return 0;
  });
};

В данном примере sortData принимает массив объектов data и строку column, которая указывает, по какому полю нужно сортировать данные. Результатом будет новый отсортированный массив.

Тестирование сортировки с использованием React Testing Library

Для того чтобы протестировать сортировку в компоненте с таблицей, потребуется несколько ключевых аспектов: тестирование пользовательского взаимодействия, проверка правильности сортировки данных и взаимодействия с DOM.

Настройка тестовой среды

Для начала необходимо подготовить тестовое окружение с использованием React Testing Library. Включим в тестовую среду компонент Table с исходными данными.

import { render, screen, fireEvent } from '@testing-library/react';
import Table from './Table';

const data = [
  { id: 1, name: 'Иван', age: 30 },
  { id: 2, name: 'Анна', age: 25 },
  { id: 3, name: 'Петр', age: 35 },
];

test('сортировка по имени', () => {
  render(<Table data={data} sortColumn="name" onS ort={() => {}} />);
  
  const nameButton = screen.getByText('Имя');
  fireEvent.click(nameButton);

  // Проверка того, что данные отсортированы по имени
  const rows = screen.getAllByRole('row');
  expect(rows[1]).toHaveTextContent('Анна');
  expect(rows[2]).toHaveTextContent('Иван');
  expect(rows[3]).toHaveTextContent('Петр');
});

В данном тесте происходит рендер компонента таблицы с переданными данными. Мы симулируем клик по кнопке “Имя”, чтобы инициировать сортировку. После этого проверяется, что строки таблицы отсортированы по алфавиту.

Тестирование логики сортировки

Для более сложных тестов, где необходимо проверить саму логику сортировки, можно создать отдельную функцию, которая будет тестировать сортировку данных до и после клика.

test('сортировка данных по возрасту', () => {
  const sortData = (data, column) => {
    return data.sort((a, b) => {
      if (a[column] < b[column]) return -1;
      if (a[column] > b[column]) return 1;
      return 0;
    });
  };

  const sortedData = sortData([...data], 'age');

  expect(sortedData[0].age).toBe(25);
  expect(sortedData[1].age).toBe(30);
  expect(sortedData[2].age).toBe(35);
});

Здесь мы тестируем именно функцию сортировки, проверяя, что данные после сортировки возрастают по возрастанию.

Тестирование состояния сортировки

Для обеспечения правильности поведения интерфейса после сортировки, нужно убедиться, что состояние компонента обновляется корректно. Например, если сортировка была выполнена по одному столбцу, то состояние компонента должно обновиться и отобразиться в пользовательском интерфейсе.

test('сортировка данных с изменением состояния', () => {
  const { rerender } = render(<Table data={data} sortColumn="name" onS ort={jest.fn()} />);
  
  // Имитируем клик по кнопке сортировки по имени
  fireEvent.click(screen.getByText('Имя'));
  
  rerender(<Table data={sortedData} sortColumn="name" onS ort={jest.fn()} />);
  
  // Проверка того, что состояние обновилось после клика
  const rows = screen.getAllByRole('row');
  expect(rows[1]).toHaveTextContent('Анна');
});

В данном тесте мы ререндерим компонент после того, как сортировка была инициирована, чтобы проверить, что изменения отображаются корректно.

Использование пользовательского события для тестирования

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

import userEvent from '@testing-library/user-event';

test('сортировка с использованием userEvent', async () => {
  render(<Table data={data} sortColumn="name" onS ort={() => {}} />);
  
  const nameButton = screen.getByText('Имя');
  await userEvent.click(nameButton);

  const rows = screen.getAllByRole('row');
  expect(rows[1]).toHaveTextContent('Анна');
});

Здесь используется userEvent для эмуляции клика, что позволяет более точно воспроизвести действия пользователя. Это особенно полезно при тестировании интерактивных элементов и асинхронных операций.

Рекомендации по тестированию сортировки

  1. Покрытие всех случаев: важно тестировать как сортировку в прямом, так и в обратном порядке. Например, при повторном клике на тот же столбец сортировка должна измениться на противоположную.
  2. Асинхронность: если сортировка зависит от асинхронных операций (например, запросов к серверу), важно тестировать правильность обновления данных после завершения этих операций.
  3. Оптимизация: в больших таблицах, содержащих большое количество данных, стоит проверять производительность сортировки, чтобы избежать возможных сбоев при обработке больших массивов.

Итоги

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