Unpoly — это JavaScript-фреймворк, предназначенный для упрощения работы с частичным обновлением страниц без полной перезагрузки. При тестировании приложений, использующих Unpoly, важно умение изолировать части интерфейса, которые зависят от внешних источников данных, чтобы тесты были быстрыми, предсказуемыми и независимыми. Для этого применяются моки и стабы.
Мок (mock) — это объект или функция, имитирующая поведение реального компонента или API. Моки используются для проверки того, как компонент взаимодействует с внешними вызовами, например, отправку AJAX-запросов или вызовы методов другого модуля.
Стаб (stub) — это более простая имитация, которая возвращает заранее определённые данные без сложной логики. Стабы нужны, чтобы контролировать данные, которые возвращаются из внешнего источника, не проверяя сами вызовы.
В контексте Unpoly эти подходы особенно полезны для:
Для тестов часто используют Jest, Jasmine или Mocha. Unpoly имеет
встроенные методы для AJAX-запросов, которые можно перехватывать и
заменять моками. Основной метод — это up.ajax, который
возвращает промис. Его можно заменить мок-функцией:
jest.spyOn(up, 'ajax').mockImplementation((options) => {
return Promise.resolve({
status: 200,
text: '<div class="mocked-content">Тестовый контент</div>'
});
});
В этом примере каждый вызов up.ajax в тестах будет
возвращать заранее определённый HTML, имитируя успешный серверный
ответ.
Иногда важно тестировать не весь AJAX, а только обновление
конкретного элемента. Для этого используют селекторы Unpoly и методы
up.render с переданными данными:
const stubContent = '<div id="user-list"><p>Пользователь 1</p></div>';
up.render('#user-list', stubContent);
Такой подход позволяет имитировать обновление части страницы без фактического обращения к серверу и без изменения остальных компонентов интерфейса.
Помимо имитации данных, важно иногда проверять, что запрос был вызван с нужными параметрами:
const ajaxMock = jest.spyOn(up, 'ajax').mockImplementation((options) => {
expect(options.url).toBe('/api/users');
expect(options.method).toBe('GET');
return Promise.resolve({ status: 200, text: '<div>OK</div>' });
});
В этом случае тест не только подставляет данные, но и подтверждает правильность использования API.
Для крупных приложений удобно создавать отдельный модуль
mocks.js, где хранятся все стабы и моки:
export const ajaxMocks = {
usersList: () => Promise.resolve({
status: 200,
text: '<div id="user-list"><p>Пользователь A</p></div>'
}),
userDetail: (id) => Promise.resolve({
status: 200,
text: `<div id="user-detail">Пользователь ${id}</div>`
})
};
Подключение к тестам через
jest.spyOn(up, 'ajax').mockImplementation(...) позволяет
централизованно управлять имитациями и легко менять данные.
Unpoly активно использует промисы и события для обновления интерфейса. Для тестирования ошибок можно мокировать отказ сервера:
jest.spyOn(up, 'ajax').mockImplementation(() => {
return Promise.reject({ status: 500, text: 'Ошибка сервера' });
});
После этого можно проверять корректное отображение сообщений об ошибке или fallback-контента.
jest.spyOn(up, 'ajax').mockImplementation((options) => {
if (options.url === '/api/users') {
return Promise.resolve({ status: 200, text: '<div>Список пользователей</div>' });
} else {
return Promise.reject({ status: 404 });
}
});
Unpoly генерирует события при рендеринге
(up:fragment:loaded, up:fragment:rendered) и
при ошибках (up:ajax:error). Моки и стабы позволяют
тестировать реакции на эти события:
document.addEventListener('up:fragment:loaded', (event) => {
expect(event.target.id).toBe('user-list');
});
Моки и стабы в Unpoly обеспечивают надежное, быстрое и предсказуемое тестирование интерфейса, позволяя сосредоточиться на логике обновления фрагментов и реакциях на данные, без зависимости от реального сервера.