В Page.js обработчики маршрутов (route handlers) являются функциями, которые вызываются при совпадении текущего URL с определённым маршрутом. Тестирование таких обработчиков необходимо для проверки корректности логики навигации, передачи параметров и взаимодействия с DOM или сторонними сервисами.
Тестирование можно разделить на два направления: юнит-тестирование самих обработчиков и интеграционное тестирование маршрутизации.
Типичный обработчик маршрута в Page.js выглядит следующим образом:
page('/user/:id', (ctx) => {
const userId = ctx.params.id;
renderUserProfile(userId);
});
Здесь ключевыми точками для тестирования являются:
ctx.path — полный путь URL.ctx.params — параметры маршрута.ctx.querystring — строка запроса.ctx.state — состояние приложения, переданное через
middleware.Юнит-тестирование предполагает проверку логики функции в
отрыве от реального маршрутизатора. Для этого создаётся
имитация (mock) объекта ctx и проверяется результат вызова
обработчика.
Пример с использованием Jest:
import { renderUserProfile } from './views';
import { userRouteHandler } from './routes';
jest.mock('./views', () => ({
renderUserProfile: jest.fn(),
}));
test('userRouteHandler передаёт правильный id в renderUserProfile', () => {
const ctx = { params: { id: '42' } };
userRouteHandler(ctx);
expect(renderUserProfile).toHaveBeenCalledWith('42');
});
Ключевые моменты:
renderUserProfile для контроля
побочного эффекта.ctx.Page.js позволяет использовать цепочки middleware:
page('/dashboard', authMiddleware, dashboardHandler);
Тестирование middleware важно для проверки логики авторизации,
подстановки данных в ctx.state или обработки ошибок.
Пример:
test('authMiddleware блокирует неавторизованного пользователя', () => {
const ctx = { state: { user: null }, redirect: jest.fn() };
authMiddleware(ctx, () => {});
expect(ctx.redirect).toHaveBeenCalledWith('/login');
});
Здесь мы проверяем, что при отсутствии пользователя вызывается
редирект, а next не вызывается.
Интеграционное тестирование предполагает проверку маршрутов в связке с Page.js, включая переходы и обновление URL. Для этого можно использовать виртуальный DOM, например jsdom, чтобы эмулировать поведение браузера.
Пример:
import page from 'page';
import { dashboardHandler } from './routes';
import { renderDashboard } from './views';
jest.mock('./views', () => ({
renderDashboard: jest.fn(),
}));
document.body.innerHTML = '<div id="app"></div>';
page('/dashboard', dashboardHandler);
page.start();
page('/dashboard');
expect(renderDashboard).toHaveBeenCalled();
expect(window.location.pathname).toBe('/dashboard');
Особенности интеграционных тестов:
page.start().window.location.pathname).Page.js позволяет передавать параметры и query string. Важно тестировать их корректную обработку:
page('/search/:term', (ctx) => {
performSearch(ctx.params.term, ctx.querystring);
});
Пример теста:
test('searchHandler передаёт параметры в performSearch', () => {
const ctx = { params: { term: 'javascript' }, querystring: 'page=2' };
const performSearch = jest.fn();
searchHandler(ctx, performSearch);
expect(performSearch).toHaveBeenCalledWith('javascript', 'page=2');
});
Обработчики могут бросать ошибки или возвращать промисы. Тестирование должно учитывать асинхронные сценарии:
test('asyncRouteHandler обрабатывает ошибки', async () => {
const ctx = {};
const next = jest.fn();
await expect(asyncRouteHandler(ctx, next)).resolves.not.toThrow();
});
Для промисов важно использовать await или
.resolves/.rejects для корректного контроля
ошибок.
ctx после
обработки.next() вызывается), так и отрицательные (редиректы,
ошибки).page('/profile/:id', authMiddleware, profileHandler);
test('полный маршрут profile', () => {
const ctx = { params: { id: '123' }, state: { user: { id: '123' } }, redirect: jest.fn() };
const next = jest.fn();
authMiddleware(ctx, next);
expect(next).toHaveBeenCalled();
profileHandler(ctx);
expect(renderProfile).toHaveBeenCalledWith('123');
});
В этом примере проверяется взаимодействие middleware с основным обработчиком, корректная передача параметров и вызов функции рендеринга.
Тестирование маршрутов в Page.js требует аккуратного моделирования
ctx, использования моков и контроля последовательности
вызовов middleware и обработчиков. Это позволяет создать надёжную и
предсказуемую навигацию в одностраничных приложениях.