JavaRush /Курсы /Модуль 3: React /Создание моков и фикстур для тестирования API

Создание моков и фикстур для тестирования API

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

Зачем нужны моки и фикстуры?

Когда ваш компонент загружает или отправляет данные на сервер (например, через запросы к API), вам нужно быть уверенным, что всё работает как следует. Однако тестировать это на реальном сервере — плохая идея. Почему?

  1. Зависимость от внешней среды: если сервер упадёт или изменится, ваши тесты начнут падать.
  2. Скорость: тесты, отправляющие реальные запросы, медленнее. Нам нужно быстро.
  3. Конфиденциальность данных: некоторые данные нельзя отправлять и использовать в реальных API.

И вот тут на помощь приходят моки и фикстуры.

  • Моки — фейковые реализации функций или объектов, которые подменяют реальные зависимости. Например, если компонент вызывает функцию fetch, вы можете замокать её и вернуть тестовые данные.
  • Фикстуры — заранее подготовленные данные, которые используются в ваших тестах. Это можно представить как "шаблонные" данные.

Создание моков для API-вызовов

Jest предоставляет встроенные функции для создания моков. Чтобы замокать вызов API, вам нужно подменить соответствующую функцию.

Пример: наш компонент использует fetch для получения данных. Давайте замокаем его.

// UserDetails.tsx — компонент
import React, { useEffect, useState } from 'react';

interface User {
  id: number;
  name: string;
  email: string;
}

const UserDetails: React.FC = () => {
  const [user, setUser] = useState<User | null>(null);

  useEffect(() => {
    const fetchUser = async () => {
      const response = await fetch('https://api.example.com/user/1');
      const data = await response.json();
      setUser(data);
    };

    fetchUser();
  }, []);

  if (!user) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      <h1>{user.name}</h1>
      <p>{user.email}</p>
    </div>
  );
};

export default UserDetails;

Теперь создадим тест для этого компонента с моками.

// UserDetails.test.tsx — тест
import React from 'react';
import { render, screen } from '@testing-library/react';
import UserDetails from './UserDetails';

// Мок для global.fetch
global.fetch = jest.fn(() =>
  Promise.resolve({
    json: () => Promise.resolve({ id: 1, name: 'John Doe', email: 'john.doe@example.com' }),
  })
) as jest.Mock;

test('renders user details after API call', async () => {
  render(<UserDetails />);

  // Ожидаем, что "загрузка" будет отображена
  expect(screen.getByText(/Loading/i)).toBeInTheDocument();

  // Ожидаем, что данные пользователя появятся
  const name = await screen.findByText(/John Doe/i); // findByText ждёт появления элемента
  expect(name).toBeInTheDocument();
});

Типичные ошибки при работе с моками

  1. Пропустили сброс мока между тестами: если ваш мок используется в нескольких тестах, всегда сбрасывайте его состояние с помощью jest.clearAllMocks() перед каждым тестом.
  2. Закомментировали вызов мока: если вы забыли замокать fetch, то тест может провалиться из-за реального вызова.

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

Представьте, что мы часто в наших тестах возвращаем одного и того же пользователя. Вместо того чтобы дублировать данные в каждом тесте, мы выносим их в отдельный файл.

Создадим фикстуру:

// fixtures/user.ts
export const userFixture = {
  id: 1,
  name: 'John Doe',
  email: 'john.doe@example.com',
};

Теперь мы можем использовать эту фикстуру в тестах:

// UserDetails.test.tsx — тест с фикстурой
import React from 'react';
import { render, screen } from '@testing-library/react';
import UserDetails from './UserDetails';
import { userFixture } from './fixtures/user';

global.fetch = jest.fn(() =>
  Promise.resolve({
    json: () => Promise.resolve(userFixture),
  })
) as jest.Mock;

test('renders user details after API call', async () => {
  render(<UserDetails />);

  const name = await screen.findByText(userFixture.name);
  expect(name).toBeInTheDocument();
});

Использование фикстур помогает сделать тесты более читаемыми и поддерживаемыми.

Использование библиотеки msw для Mock API

Если ваш компонент взаимодействует с несколькими API или вы хотите точнее замокать сетевые запросы, библиотека MSW (Mock Service Worker) становится вашим спасителем.

Установка MSW

Установите библиотеку:

npm install msw --save-dev

Настройка MSW

  1. Создайте файл с моком API.
// mocks/handlers.ts
import { rest } from 'msw';
import { userFixture } from '../fixtures/user';

export const handlers = [
  rest.get('https://api.example.com/user/1', (req, res, ctx) => {
    return res(ctx.json(userFixture));
  }),
];
  1. Настройте MSW в тестах:
// setupTests.ts
import { setupServer } from 'msw/node';
import { handlers } from './mocks/handlers';

const server = setupServer(...handlers);

// Запуск сервера перед всеми тестами
beforeAll(() => server.listen());
// Сбрасываем обработчики после каждого теста
afterEach(() => server.resetHandlers());
// Останавливаем сервер после завершения тестов
afterAll(() => server.close());
  1. Используйте в тестах:
// UserDetails.test.tsx — тест с MSW
import React from 'react';
import { render, screen } from '@testing-library/react';
import UserDetails from './UserDetails';

test('renders user details after API call', async () => {
  render(<UserDetails />);
  const name = await screen.findByText(/John Doe/i);
  expect(name).toBeInTheDocument();
});

Моки vs фикстуры: когда использовать?

  • Моки: подходят для имитации поведения функций и внешних зависимостей.
  • Фикстуры: используются для управления тестовыми данными (будь то статический JSON или фальшивые данные объектов).

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

Советы и типичные ошибки при тестировании API

Тестирование API часто вызывает путаницу. Вот несколько советов, чтобы избежать проблем:

  1. Всегда сбрасывайте состояние моков между тестами. Используйте jest.clearAllMocks() или jest.resetModules() в блоке afterEach.
  2. Проверяйте не только успешные кейсы, но и ошибки. Например, что компонент корректно обрабатывает ошибки API (например, возвращает "Произошла ошибка").
  3. Если моки слишком сложны, подумайте об msw. MSW позволяет легко создать реалистичное поведение API.
  4. Держите ваши мок-данные и фикстуры компактными и легко читаемыми. Большие файлы сложно отлаживать.

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

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