jest.setup.js
Обзор
Файл jest.setup.js предназначен для настройки среды тестирования с использованием Jest в проекте на основе React и Next.js. В нем реализованы моки (заглушки) для различных внешних зависимостей и API, таких как маршрутизатор Next.js, клиент socket.io, HTTP-библиотека axios, а также нативные браузерные API window.matchMedia, IntersectionObserver и ResizeObserver. Это позволяет запускать тесты без реального вызова сетевых запросов или взаимодействия с браузерными API, что повышает стабильность и скорость тестирования.
Данный файл обычно подключается в конфигурации Jest как setup-файл, который выполняется один раз перед всеми тестами.
Подробное описание компонентов и моков
Импорт
import '@testing-library/jest-dom'
Подключает расширения jest-dom для удобных матчеров в тестах (например, toBeInTheDocument()).
Мок Next.js Router
jest.mock('next/navigation', () => ({
useRouter() {
return {
push: jest.fn(),
replace: jest.fn(),
prefetch: jest.fn(),
back: jest.fn(),
forward: jest.fn(),
refresh: jest.fn(),
}
},
useSearchParams() {
return new URLSearchParams()
},
usePathname() {
return ''
},
}))
useRouter() — возвращает объект с методами маршрутизатора, все методы замоканы через
jest.fn().
Методы:push(url: string): void— переход на указанный URL.replace(url: string): void— замена текущего URL.prefetch(url: string): void— предзагрузка страницы.back(): void— переход назад.forward(): void— переход вперед.refresh(): void— обновление текущей страницы.
useSearchParams() — возвращает пустой объект
URLSearchParams, имитирующий параметры запроса.usePathname() — возвращает пустую строку, имитируя текущий путь.
Пример использования в тестах:
import { useRouter } from 'next/navigation'
test('router push вызывается', () => {
const router = useRouter()
router.push('/home')
expect(router.push).toHaveBeenCalledWith('/home')
})
Мок socket.io-client
jest.mock('socket.io-client', () => ({
io: jest.fn(() => ({
on: jest.fn(),
emit: jest.fn(),
close: jest.fn(),
})),
}))
io()— функция создания клиента сокетов, возвращает объект с замоканными методами:on(event: string, callback: Function): void— подписка на событие.emit(event: string, data: any): void— отправка события.close(): void— закрытие соединения.
Это позволяет тестировать функциональность, связанную с WebSocket, без реального подключения.
Мок axios
jest.mock('axios', () => ({
default: {
get: jest.fn(() => Promise.resolve({ data: {} })),
post: jest.fn(() => Promise.resolve({ data: {} })),
put: jest.fn(() => Promise.resolve({ data: {} })),
delete: jest.fn(() => Promise.resolve({ data: {} })),
},
}))
Все HTTP методы (
get,post,put,delete) возвращают промис, который резолвится пустым объектом{ data: {} }.Позволяет тестировать компоненты и сервисы, делающие HTTP-запросы, без реальных сетевых вызовов.
Пример использования:
import axios from 'axios'
test('axios get вызывается', async () => {
const response = await axios.get('/api/data')
expect(response.data).toEqual({})
expect(axios.get).toHaveBeenCalledWith('/api/data')
})
Мок window.matchMedia
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation(query => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // deprecated
removeListener: jest.fn(), // deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
})
Переопределяет
window.matchMediaдля поддержки тестов, зависящих от медиа-запросов.Все методы мокированы, а
matchesвсегдаfalse.Позволяет избежать ошибок при рендеринге компонентов, использующих адаптивность.
Мок IntersectionObserver
global.IntersectionObserver = class IntersectionObserver {
constructor() {}
observe() {
return null
}
disconnect() {
return null
}
unobserve() {
return null
}
}
Заглушка для API наблюдения пересечения элементов с областью видимости.
Методы пустые, возвращают
null.Используется для компонентов, которые зависят от этого API (например, ленивый рендеринг, анимации).
Мок ResizeObserver
global.ResizeObserver = class ResizeObserver {
constructor() {}
observe() {
return null
}
disconnect() {
return null
}
unobserve() {
return null
}
}
Аналогично
IntersectionObserver, заглушка для API наблюдения за изменением размеров элементов.
Взаимодействие с другими частями системы
Этот файл выполняется перед запуском тестов и подменяет реальные реализации некоторых модулей и браузерных API на заглушки.
Благодаря этому, тесты становятся изолированными от внешних сервисов и системных API, что улучшает стабильность и воспроизводимость тестов.
Используется с Jest и React Testing Library, особенно в проектах на Next.js с socket.io и axios.
Помогает избежать ошибок типа "window.matchMedia is not a function" или проблем с маршрутизатором Next.js при тестировании компонентов.
Визуальная диаграмма структуры файла
Файл представляет собой набор моков без классов и функций, поэтому уместна диаграмма потока, показывающая основную структуру моков и их взаимосвязи.
flowchart TD
A[jest.setup.js] --> B[Mock Next.js Router]
A --> C[Mock socket.io-client]
A --> D[Mock axios]
A --> E[Mock window.matchMedia]
A --> F[Mock IntersectionObserver]
A --> G[Mock ResizeObserver]
B --> B1[useRouter() с методами push, replace, prefetch, back, forward, refresh]
B --> B2[useSearchParams() возвращает URLSearchParams]
B --> B3[usePathname() возвращает пустую строку]
C --> C1[io() возвращает on, emit, close]
D --> D1[get, post, put, delete возвращают Promise с {data: {}}]
E --> E1[matchMedia возвращает объект с matches, media, addListener и др.]
F --> F1[observe(), disconnect(), unobserve() — пустые методы]
G --> G1[observe(), disconnect(), unobserve() — пустые методы]
Резюме
Файл jest.setup.js — это конфигурационный файл для Jest, который обеспечивает:
Мокирование важных внешних зависимостей и API (Next.js router, socket.io, axios).
Заглушки для браузерных API (matchMedia, IntersectionObserver, ResizeObserver).
Стабильное и изолированное тестирование React-компонентов и логики без реальных сетевых и системных вызовов.
Это стандартная и необходимая практика для обеспечения качества и надежности тестов в современных веб-приложениях на React и Next.js.