Механизм мокирования API позволяет изолировать тестируемый код от внешних зависимостей и сетевого окружения. При работе с Karma это особенно важно, поскольку тесты запускаются в браузерах, а сетевые запросы могут быть нестабильны, медленны или вовсе недоступны. Моки обеспечивают детерминированность тестов и помогают воспроизводить сценарии, которые сложно получить при реальном взаимодействии с сервером.
Использование моков API необходимо, когда:
В экосистеме JavaScript наибольшее распространение получили Sinon.js, Jasmine Spies и встроенные механизмы фреймворков тестирования. При использовании Karma выбор инструмента зависит от предпочтений и стека проекта.
Sinon.js предоставляет фейки для
XMLHttpRequest, таймеров и функций. Это удобно, когда код
активно использует классические XHR-запросы или setTimeout.
Jasmine Spies позволяет перехватывать вызовы функций и
задавать ожидаемые результаты, а также проверять количество вызовов и
аргументы. В случае, когда приложение использует современный
fetch, можно применить специальные моки через
sinon.fake() или через патчинг глобального объекта
window.fetch.
Выстраивание корректной архитектуры мокирования требует ясной границы между тестируемой логикой и адаптерами к API. Инкапсуляция HTTP-клиента в отдельный модуль облегчает подмену этого слоя в тестах. Вместо создания моков для каждой сетевой операции полезно абстрагировать транспорт и тестировать только бизнес-логику.
Ключевой принцип: моки не должны искажать поведение системы сильнее, чем это необходимо. Ответы сервера должны быть близки к реальным, включая поля, типы данных и формат ошибок.
describe('Service: UserService', function() {
var xhr, requests, service;
beforeEach(function() {
xhr = sinon.useFakeXMLHttpRequest();
requests = [];
xhr.onCREATE = function(req) { requests.push(req); };
module('app');
inject(function(_UserService_) {
service = _UserService_;
});
});
afterEach(function() {
xhr.restore();
});
it('должен получать профиль пользователя', function(done) {
service.getProfile(42).then(function(profile) {
expect(profile.id).toBe(42);
expect(profile.name).toBe('Alice');
done();
});
requests[0].respond(
200,
{ 'Content-Type': 'application/json' },
JSON.stringify({ id: 42, name: 'Alice' })
);
});
});
В данном примере используется подмена XMLHttpRequest
средствами Sinon. Через respond формируется ответ сервера,
а дальнейшая обработка тестируется без реального сетевого вызова. Karma
обеспечивает контроль запуска браузера и сбор отчетов, а Sinon отвечает
за управление сетевым слоем.
Современные приложения чаще используют fetch. В этом
случае подмена осуществляется через фейковую функцию, возвращающую
промис:
window.fetch = sinon.fake.resolves(
new Response(JSON.stringify({ status: 'ok' }), {
status: 200,
headers: { 'Content-Type': 'application/json' }
})
);
Такой подход удобно комбинировать с библиотеками-полифилами и проверять, как код реагирует на различные статусы и содержимое ответа.
Тестирование ошибок сервера требует моков с отказами
(reject) или статусами 4xx/5xx. Для
тестирования таймаутов Sinon предоставляет фейковые таймеры, позволяющие
управлять временем в тестах и синхронно проверять асинхронную
логику.
Важно: таймеры и сетевые моки следует использовать согласованно, чтобы исключить состояния гонки и недетерминированность результатов.
Для крупных проектов рекомендуется выделять каталоги с фикстурами ответов API. Это уменьшает дублирование данных, повышает читаемость тестов и облегчает поддержку. Фикстуры должны быть описательными и актуальными относительно API.
Пример структуры проекта:
test/
fixtures/
user/
profile.json
preferences.json
billing/
invoice.json
unit/
userService.spec.js
billingService.spec.js
Фикстуры подключаются в тесты и используются для формирования ответов.
Karma поддерживает множество препроцессоров, которые могут подгружать JSON-файлы фикстур и отдавать их в тесты как модули. Это упрощает мокирование API и снижает объем ручной работы. В конфигурации Karma возможно указать препроцессоры для JSON, чтобы использовать их как обычные объекты.
Чрезмерное использование моков приводит к тестированию не реального поведения системы, а искусственной среды. Применение моков оправдано только там, где существует внешняя зависимость. Моки не должны подменять внутреннюю логику, которую требуется протестировать. При необходимости интеграционные тесты могут запускаться с реальным сервером или локальным эмулятором.
Мокирование облегчает создание сложных сценариев: очереди запросов, отмена запросов, повторная авторизация после истечения токена, обработка редких статус-кодов. Благодаря этому формируются кейсы, которые трудно или опасно воспроизводить в боевых условиях. Репликация таких ситуаций ускоряет разработку и улучшает надежность системы.
Мокирование API при работе с Karma формирует стабильный, воспроизводимый и контролируемый контур тестирования. Использование корректных инструментов и продуманной архитектуры моков обеспечивает изоляцию логики, высокую скорость и достоверные результаты тестов.