0Pricing
Frontend Academy · Урок

Имитация модулей и API-вызовов

Имитируйте ES-модули с помощью jest.mock(), подменяйте fetch через MSW (Mock Service Worker) и тестируйте компоненты, зависящие от внешних данных, без настоящих сетевых вызовов.

«Имитация модулей и API-вызовов» — бесплатный урок Frontend Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Frontend Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Frontend Academy содержит 4 уроков всего.

Зачем нужны имитации

Модульные тесты должны быть изолированными. Реальные вызовы API медленные, ненадёжные и дорогостоящие. Имитация заменяет зависимости управляемыми тестовыми двойниками, которые возвращают предсказуемые ответы.

jest.mock() — имитация целых модулей

jest.mock('module-path') заменяет весь модуль автоматически созданными имитациями. Все экспорты становятся заглушками jest.fn(). Вызывайте mockReturnValue или mockResolvedValue, чтобы задать возвращаемые значения.

jest.mock('./api');
import { fetchUser } from './api';

(fetchUser as jest.Mock).mockResolvedValue({ id: 1, name: 'Alice' });

test('renders user name', async () => {
  render(<Profile userId="1" />);
  await screen.findByText('Alice');
  expect(fetchUser).toHaveBeenCalledWith('1');
});

jest.fn() — ручные заглушки

jest.fn() создаёт имитируемую функцию, вызовы которой можно отслеживать и которой можно управлять. Это полезно для свойств с функциями обратного вызова и зависимостей служб.

const onSubmit = jest.fn();
render(<Form onSubmit={onSubmit} />);

await user.click(screen.getByRole('button', { name: /submit/i }));

expect(onSubmit).toHaveBeenCalledOnce();
expect(onSubmit).toHaveBeenCalledWith({ email: 'alice@example.com' });

Сброс имитаций в beforeEach

Сбрасывайте имитации между тестами, чтобы предотвратить утечку состояния. Используйте jest.clearAllMocks() в beforeEach.

beforeEach(() => {
  jest.clearAllMocks(); // reset call counts and implementations
});

afterAll(() => {
  jest.restoreAllMocks(); // restore original implementations
});

MSW — Mock Service Worker

MSW перехватывает реальные вызовы fetch/XHR на сетевом уровне с помощью Service Workers в браузере или перехватчиков Node.js в тестах. Пишите обработчики запросов, возвращающие фиктивные ответы.

import { setupServer } from 'msw/node';
import { http, HttpResponse } from 'msw';

const server = setupServer(
  http.get('/api/users', () => {
    return HttpResponse.json([{ id: 1, name: 'Alice' }]);
  })
);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

Переопределения MSW для отдельных тестов

Переопределяйте обработчик по умолчанию для конкретного сценария теста.

test('handles server error', async () => {
  server.use(
    http.get('/api/users', () => new HttpResponse(null, { status: 500 }))
  );

  render(<UserList />);
  await screen.findByText(/server error/i);
});

Имитация localStorage

Используйте jest.spyOn для имитации методов веб-хранилища в тестах, использующих localStorage.

beforeEach(() => {
  const store: Record<string, string> = {};
  jest.spyOn(Storage.prototype, 'getItem').mockImplementation((key) => store[key] ?? null);
  jest.spyOn(Storage.prototype, 'setItem').mockImplementation((key, val) => { store[key] = val; });
});

Имитация таймеров

jest.useFakeTimers() заменяет setTimeout/setInterval версиями, управляемыми Jest. jest.runAllTimers() мгновенно запускает все таймеры.

jest.useFakeTimers();

test('shows toast for 3 seconds', () => {
  render(<Toast message="Saved!" />);
  expect(screen.getByText('Saved!')).toBeInTheDocument();

  jest.advanceTimersByTime(3000);
  expect(screen.queryByText('Saved!')).not.toBeInTheDocument();
});

afterEach(() => jest.useRealTimers());

Фабричный шаблон модулей

В TypeScript фабрики имитируемых модулей возвращают правильные типы.

jest.mock('./services/auth', () => ({
  login: jest.fn().mockResolvedValue({ token: 'test-token' }),
  logout: jest.fn()
}));

Тестирование по снимкам — используйте умеренно

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

Быстрая проверка

Каково главное преимущество MSW перед jest.mock('fetch') для имитации программного интерфейса?

Повторение: имитация

jest.mock() заменяет модули. jest.fn() создаёт отслеживаемые заглушки. Сбрасывайте заглушки в beforeEach. MSW перехватывает запросы на сетевом уровне — это наиболее реалистичный подход к имитации. Переопределения server.use() для отдельных тестов позволяют моделировать сценарии ошибок. Используйте фиктивные таймеры для кода, зависящего от времени. Для интеграционных тестов компонентов предпочтительнее MSW.

Часто задаваемые вопросы

Урок «Имитация модулей и API-вызовов» бесплатный?

Да — полный текст урока «Имитация модулей и API-вызовов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Frontend Academy, подпишись на CoddyKit PRO. Курс Frontend Academy содержит 4 уроков всего.

Чему я научусь в уроке «Имитация модулей и API-вызовов»?

Имитируйте ES-модули с помощью jest.mock(), подменяйте fetch через MSW (Mock Service Worker) и тестируйте компоненты, зависящие от внешних данных, без настоящих сетевых вызовов. Ты практикуешь Frontend Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Frontend Academy?

Предыдущий опыт не требуется. Frontend Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Имитация модулей и API-вызовов»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Frontend Academy?

Да. Каждый урок Frontend Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Настройка Jest и базовые тесты
  2. @testing-library/react: render и userEvent
  3. @testing-library/vue: монтирование компонентов
  4. Имитация модулей и API-вызовов
← Назад к Frontend Academy