JavaRush /Курсы /Модуль 3: React /Проверка значений пропсов и состояния компонента

Проверка значений пропсов и состояния компонента

Модуль 3: React
17 уровень , 5 лекция
Открыта

Зачем тестировать пропсы и состояние?

Если вы помните, в React пропсы и состояние — это как мозг и сердце вашего интерфейса. Они управляют тем, что видит пользователь, и как приложение реагирует на его действия:

  1. Пропсы — это внешний источник данных, который передаётся в компоненты.
  2. Состояние — это внутренний механизм управления динамическими данными внутри компонентов.

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

Пример приложения

Мы продолжим работать с маленьким учебным приложением — списком заметок. В нём есть возможность добавлять новые заметки и отображать их на экране. Вот наш текущий компонент:

import React, { useState } from "react";

interface Note {
  id: number;
  text: string;
}

interface NoteListProps {
  notes: Note[];
}

export const NoteList: React.FC<NoteListProps> = ({ notes }) => {
  const [inputValue, setInputValue] = useState("");

  const addNote = () => {
    alert(`New note added: ${inputValue}`);
    setInputValue("");
  };

  return (
    <div>
      <ul>
        {notes.map((note) => (
          <li key={note.id}>{note.text}</li>
        ))}
      </ul>
      <input
        data-testid="note-input"
        value={inputValue}
        onChange={(e) => setInputValue(e.target.value)}
      />
      <button data-testid="add-note-button" onClick={addNote}>
        Add Note
      </button>
    </div>
  );
};

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

Шаг 1: проверка начальных значений пропсов

Чтобы проверить, что компонент корректно отображает переданные данные, используем render() и методы поиска из React Testing Library.

import { render, screen } from "@testing-library/react";
import { NoteList } from "./NoteList";

test("должен рендерить переданные заметки", () => {
  const mockNotes = [
    { id: 1, text: "Note 1" },
    { id: 2, text: "Note 2" },
  ];

  render(<NoteList notes={mockNotes} />);

  // Проверяем, что каждая заметка отображается
  mockNotes.forEach((note) => {
    expect(screen.getByText(note.text)).toBeInTheDocument();
  });
});
💡 Совет:

Если ваш компонент ожидает сложную структуру пропсов, создайте фикстуру (готовые тестовые данные). Это упрощает повторное использование данных в разных тестах.

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

Шаг 2: проверка начального состояния

Начальное состояние — это то, где всё начинается. Проверим, что поле ввода пустое при загрузке компонента.


    import { render, screen } from "@testing-library/react";

test("должен показывать пустое поле ввода по умолчанию", () => {
  const mockNotes = [];
  render(<NoteList notes={mockNotes} />);

  const input = screen.getByTestId("note-input");
  expect(input).toHaveValue(""); // Проверяем начальное состояние
});

Шаг 3: проверка изменения состояния

Пользовательский ввод и клики изменяют состояние компонента. Используем fireEvent для симуляции этих действий.

import { render, screen, fireEvent } from "@testing-library/react";

test("должен обновлять состояние при вводе текста", () => {
  render(<NoteList notes={[]} />);

  const input = screen.getByTestId("note-input");

  fireEvent.change(input, { target: { value: "New note" } });
  expect(input).toHaveValue("New note"); // Проверка обновленного состояния
});

Тестирование взаимодействия пропсов и состояния

Часто состояние зависит от пропсов или, наоборот, пропсы передаются в зависимости от состояния. Проверим, что добавление заметки очищает поле ввода:

test("должен очищать поле ввода после добавления заметки", () => {
  render(<NoteList notes={[]} />);

  const input = screen.getByTestId("note-input");
  const button = screen.getByTestId("add-note-button");

  fireEvent.change(input, { target: { value: "New note" } });
  fireEvent.click(button); // Симулируем добавление заметки

  expect(input).toHaveValue(""); // Поле ввода должно быть очищено
});

Ошибки, которые можно встретить

Если тесты падают, это часто связано с:

  • Неправильным селектором (например, data-testid не установлен).
  • Забытой симуляцией события.
  • Неправильной проверкой на начальное состояние.

Как тесты упрощают жизнь разработчика?

  1. Стабильность: убедитесь, что данные, которые приходят в компонент через пропсы, отображаются корректно и без неожиданностей.
  2. Гарантия работы: тестирование состояния даёт уверенность, что вся логика работы компонента соответствует требованиям.
  3. Гибкость: как только вы добавите новых пользователей или функционал, тесты покажут, сломали вы что-нибудь или нет. Это особенно важно для живых приложений.

Заключительный пример: пользовательское взаимодействие

Давайте объединим все знания в один тест, который проверяет полный сценарий:

  1. Отобразить заметки.
  2. Ввести новую заметку.
  3. Добавить её (только в UI, поскольку реальная логика добавления не реализована).
test("полный сценарий добавления заметки", () => {
  const mockNotes = [{ id: 1, text: "Note 1" }];
  render(<NoteList notes={mockNotes} />);

  // Проверяем начальное состояние
  expect(screen.getByText("Note 1")).toBeInTheDocument();

  const input = screen.getByTestId("note-input");
  const button = screen.getByTestId("add-note-button");

  // Симулируем добавление новой заметки
  fireEvent.change(input, { target: { value: "New note" } });
  fireEvent.click(button);

  // Убедитесь в состоянии после добавления заметки
  expect(input).toHaveValue(""); // Поле ввода должно быть очищено
  expect(window.alert).toHaveBeenCalledWith("New note added: New note"); // Проверяем alert
});
// Вспомогательная настройка для подавления alert в тестах:
beforeAll(() => {
  jest.spyOn(window, "alert").mockImplementation(() => {});
});

Используя эти методики, вы сможете тестировать как статические, так и динамические компоненты в React-приложениях, делая их надёжными и готовыми к выкатке даже на очень требовательные проекты!

2
Задача
Модуль 3: React, 17 уровень, 5 лекция
Недоступна
Тестирование начального отображения компонента
Тестирование начального отображения компонента
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ