Пробросивание props и их проверка

В React компоненты могут принимать данные через props (свойства), что позволяет настраивать поведение и внешний вид компонента. При тестировании React-компонентов важно убедиться, что правильные значения props передаются в компоненты и корректно используются. React Testing Library предоставляет инструменты для работы с такими ситуациями и проверки правильности работы с пропсами.

Что такое props в React?

Props — это механизм, с помощью которого родительский компонент передаёт данные в дочерние компоненты. Эти данные могут быть любыми: строками, числами, функциями, массивами или объектами. Например, компонент, отображающий информацию о пользователе, может принимать name и age как пропсы:

function UserProfile({ name, age }) {
  return (
    <div>
      <h1>{name}</h1>
      <p>Возраст: {age}</p>
    </div>
  );
}

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

Основные методы для тестирования пропсов

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

  • render() — рендерит компонент и позволяет взаимодействовать с ним через доступные в библиотеке утилиты.
  • screen.getByText() — позволяет искать элементы по их текстовому содержимому, что особенно полезно для проверки значения, переданного через props.
  • screen.getByTestId() — находит элементы через атрибут data-testid, если элемент не имеет четко выраженного текстового содержимого.

Проверка значений props

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

Пример теста компонента UserProfile, который принимает name и age как props:

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

test('отображает имя и возраст пользователя', () => {
  render(<UserProfile name="Иван" age={30} />);
  
  // Проверка правильности отображения имени
  expect(screen.getByText('Иван')).toBeInTheDocument();
  
  // Проверка правильности отображения возраста
  expect(screen.getByText('Возраст: 30')).toBeInTheDocument();
});

В данном примере компонент UserProfile получает два пропса — name и age. Тест проверяет, что на экране отображается правильное имя и возраст, переданные в качестве props.

Проверка динамических пропсов

Многие компоненты могут изменять своё состояние или props в процессе работы. В таком случае важно протестировать, как компонент реагирует на изменения этих данных. Например, если name или age изменяются после первоначального рендеринга, компонент должен корректно обновить отображаемое содержимое.

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

test('обновление отображаемых данных при изменении props', () => {
  const { rerender } = render(<UserProfile name="Иван" age={30} />);
  
  // Проверка первоначального состояния
  expect(screen.getByText('Иван')).toBeInTheDocument();
  expect(screen.getByText('Возраст: 30')).toBeInTheDocument();
  
  // Обновляем пропсы
  rerender(<UserProfile name="Мария" age={25} />);
  
  // Проверка обновлённого состояния
  expect(screen.getByText('Мария')).toBeInTheDocument();
  expect(screen.getByText('Возраст: 25')).toBeInTheDocument();
});

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

Проверка функций, переданных через props

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

Пример компонента с колбэком:

function Button({ onClick }) {
  return <button onCl ick={onClick}>Нажми меня</button>;
}

Тест, который проверяет вызов функции, переданной через пропс onClick:

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

test('вызывает функцию при клике', () => {
  const mockOnClick = jest.fn(); // Мокаем функцию

  render(<Button onCl ick={mockOnClick} />);
  
  // Симулируем клик по кнопке
  fireEvent.click(screen.getByText('Нажми меня'));
  
  // Проверяем, что функция была вызвана
  expect(mockOnClick).toHaveBeenCalledTimes(1);
});

В этом примере создаётся мок-функция с помощью jest.fn(), которая передаётся в компонент Button. При клике на кнопку проверяется, что функция была вызвана.

Использование пропсов для условного рендеринга

Компоненты часто используют переданные props для изменения структуры интерфейса, например, для условного отображения элементов.

Пример компонента, который отображает сообщение, если isLoggedIn равно true:

function WelcomeMessage({ isLoggedIn }) {
  return isLoggedIn ? <p>Добро пожаловать!</p> : <p>Пожалуйста, войдите в систему.</p>;
}

Тестирование такого компонента:

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

test('отображает сообщение о приветствии для авторизованного пользователя', () => {
  render(<WelcomeMessage isLoggedIn={true} />);
  
  expect(screen.getByText('Добро пожаловать!')).toBeInTheDocument();
});

test('отображает просьбу войти в систему для неавторизованного пользователя', () => {
  render(<WelcomeMessage isLoggedIn={false} />);
  
  expect(screen.getByText('Пожалуйста, войдите в систему.')).toBeInTheDocument();
});

Тесты проверяют, что в зависимости от значения isLoggedIn компонент корректно отображает разные сообщения.

Работа с пропсами по умолчанию

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

Пример компонента с дефолтными пропсами:

function Greeting({ name = 'Гость' }) {
  return <h1>Привет, {name}!</h1>;
}

Тестирование:

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

test('отображает дефолтное имя, если prop не передан', () => {
  render(<Greeting />);
  
  expect(screen.getByText('Привет, Гость!')).toBeInTheDocument();
});

test('отображает переданное имя', () => {
  render(<Greeting name="Иван" />);
  
  expect(screen.getByText('Привет, Иван!')).toBeInTheDocument();
});

Здесь первый тест проверяет, что по умолчанию отображается имя “Гость”, если пропс name не был передан. Второй тест проверяет, что при передаче пропса name компонент корректно отображает переданное имя.

Заключение

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