Navigo — это легковесная библиотека для управления маршрутизацией в одностраничных приложениях на JavaScript. При разработке сложных приложений часто возникает необходимость тестировать маршруты и переходы между ними без реального изменения URL браузера или без обращения к серверу. Для этого используется мокирование навигации, которое позволяет имитировать работу роутера в изолированной среде.
Для тестирования маршрутов создаётся отдельный экземпляр Navigo. Важно при этом указать правильный базовый путь, если приложение работает не с корня домена:
import Navigo from 'navigo';
const router = new Navigo('/', { hash: true });
Ключевые моменты при создании экземпляра для мокирования:
navigate и
resolve, чтобы контролировать переходы.Метод navigate(path, options) выполняет переход к
указанному маршруту. Для тестов его часто заменяют на
функцию-заглушку:
router.navigate = (path, options) => {
console.log(`Переход к маршруту: ${path}`, options);
return Promise.resolve();
};
Такое мокирование позволяет:
При интеграционных и модульных тестах удобно использовать библиотеки типа Jest или Sinon:
import sinon from 'sinon';
const navigateSpy = sinon.spy(router, 'navigate');
router.navigate('/home');
console.assert(navigateSpy.calledOnce, 'navigate должен быть вызван один раз');
console.assert(navigateSpy.calledWith('/home'), 'navigate должен быть вызван с /home');
Преимущества использования spy:
Navigo позволяет назначать обработчики маршрутов через метод
on. Для тестов эти обработчики заменяют на заглушки:
const homeHandler = jest.fn();
router.on('/home', homeHandler);
router.resolve('/home');
expect(homeHandler).toHaveBeenCalled();
Особенности мокирования обработчиков:
resolve(path) инициирует обработку маршрута без
фактического перехода.В сложных приложениях часто вызывается
window.history.pushState или window.location.
Для изоляции тестов эти методы можно переопределять:
const originalPushState = window.history.pushState;
window.history.pushState = jest.fn();
router.navigate('/about');
expect(window.history.pushState).toHaveBeenCalledWith({}, '', '/about');
window.history.pushState = originalPushState;
Зачем это нужно:
Для полного тестирования навигации часто комбинируют мокирование:
Пример комбинированного подхода:
router.navigate = jest.fn();
const dashboardHandler = jest.fn();
router.on('/dashboard', dashboardHandler);
router.navigate('/dashboard');
router.resolve('/dashboard');
expect(router.navigate).toHaveBeenCalledWith('/dashboard');
expect(dashboardHandler).toHaveBeenCalled();
/user/:id).Navigo поддерживает параметры в маршрутах. Для тестирования это важно:
const userHandler = jest.fn();
router.on('/user/:id', userHandler);
router.resolve('/user/42');
expect(userHandler).toHaveBeenCalled();
expect(userHandler.mock.calls[0][0].params.id).toBe('42');
Ключевые моменты:
params обработчику.Метод navigate принимает объект с опциями, например
{ updateBrowserURL: false }. При мокировании важно
учитывать эти опции:
router.navigate = jest.fn((path, options) => options);
const options = router.navigate('/settings', { updateBrowserURL: false });
expect(options.updateBrowserURL).toBe(false);
Это позволяет:
navigate для контроля переходов.on и
resolve.Такой подход обеспечивает полное покрытие логики маршрутизации в тестах и позволяет создавать надёжные одностраничные приложения с динамическими маршрутами и сложными переходами.