Тестирование кода, который взаимодействует с сервером, является важной частью процесса разработки. В реальных условиях ответы от сервера могут быть медленными или нестабильными, что усложняет процесс тестирования. Чтобы избежать таких проблем, можно использовать симуляцию серверных ответов. В Jasmine для этой цели обычно применяют шпионов и моки, позволяя эмулировать поведение HTTP-запросов без необходимости реально отправлять их на сервер.
spyOn для перехвата запросовМетод spyOn в Jasmine позволяет шпионить за функциями,
перехватывая их вызовы и предоставляя возможность заменять их
реализации. Это полезно при тестировании кода, который выполняет
HTTP-запросы.
Для начала рассмотрим базовый пример, где нужно симулировать ответ сервера, чтобы проверить правильность обработки данных.
describe('Симуляция ответов сервера с использованием spyOn', function() {
it('Должен корректно обработать успешный ответ от сервера', function() {
const httpService = {
getData: function(url) {
return fetch(url).then(response => response.json());
}
};
const mockResponse = { success: true, data: 'Test Data' };
spyOn(window, 'fetch').and.returnValue(Promise.resolve({
json: () => Promise.resolve(mockResponse)
}));
httpService.getData('/test-url').then(response => {
expect(response).toEqual(mockResponse);
});
});
});
В этом примере метод fetch был перехвачен с помощью
spyOn, и вместо реального выполнения HTTP-запроса
возвращается промис с заранее подготовленным ответом. Это позволяет
тестировать логику обработки данных без необходимости выполнять реальные
запросы.
Моки — это специальные объекты, которые имитируют поведение настоящих объектов, но предоставляют фиксированное поведение для тестов. В случае с симуляцией ответов сервера моки могут быть полезны для более сложных сценариев, когда нужно контролировать не только успешные, но и ошибочные ответы.
describe('Мок серверного ответа с ошибкой', function() {
it('Должен корректно обработать ошибку сервера', function() {
const httpService = {
getData: function(url) {
return fetch(url).then(response => response.json());
}
};
const mockErrorResponse = { error: 'Server Error' };
spyOn(window, 'fetch').and.returnValue(Promise.reject(mockErrorResponse));
httpService.getData('/test-url').catch(error => {
expect(error).toEqual(mockErrorResponse);
});
});
});
Здесь с помощью spyOn на fetch мы
симулируем отклонённый промис с ошибкой, что позволяет протестировать
обработку ошибок в коде, который зависит от внешнего сервера.
jasmine-ajaxВ некоторых случаях, когда необходимо более детально контролировать
поведение HTTP-запросов, можно использовать дополнительные библиотеки,
такие как jasmine-ajax. Эта библиотека предоставляет
удобные методы для работы с AJAX-запросами, включая их имитацию.
Для использования jasmine-ajax необходимо сначала
настроить библиотеку:
beforeEach(function() {
jasmine.Ajax.install();
});
afterEach(function() {
jasmine.Ajax.uninstall();
});
Затем можно использовать методы jasmine.Ajax.requests
для контроля запросов. Например, чтобы симулировать ответ на
AJAX-запрос:
describe('Симуляция AJAX запросов с использованием jasmine-ajax', function() {
it('Должен обработать успешный ответ от сервера', function() {
const httpService = {
getData: function(url) {
return $.ajax({ url: url, method: 'GET' });
}
};
httpService.getData('/test-url');
const request = jasmine.Ajax.requests.mostRecent();
request.respondWith({
status: 200,
responseText: '{"success": true, "data": "Test Data"}'
});
request.done(function(response) {
expect(response.success).toBe(true);
expect(response.data).toBe('Test Data');
});
});
});
В этом примере мы не только контролируем ответ сервера, но и задаём
статус и текст ответа через respondWith, что даёт полный
контроль над тестируемыми запросами.
В реальных условиях запросы к серверу могут занимать разное время. Для симуляции таких задержек можно использовать таймеры или мокировать время ответа сервера.
describe('Симуляция задержки при получении данных', function() {
it('Должен обработать задержку ответа сервера', function(done) {
const httpService = {
getData: function(url) {
return new Promise(resolve => {
setTimeout(() => resolve({ success: true, data: 'Delayed Data' }), 1000);
});
}
};
const mockResponse = { success: true, data: 'Delayed Data' };
spyOn(httpService, 'getData').and.callFake(function() {
return new Promise(resolve => {
setTimeout(() => resolve(mockResponse), 1000);
});
});
httpService.getData('/test-url').then(response => {
expect(response).toEqual(mockResponse);
done();
});
});
});
В данном примере используется setTimeout для имитации
задержки. Важно помнить, что в Jasmine для асинхронных тестов нужно
использовать функцию done, чтобы указать завершение
теста.
jasmine-ajaxПомимо симуляции ответов, можно проверить, какие именно запросы были отправлены и как они были сформированы. Это особенно полезно, когда нужно удостовериться, что запросы отправляются с правильными параметрами и заголовками.
describe('Проверка запросов с использованием jasmine-ajax', function() {
it('Должен отправить запрос с правильными параметрами', function() {
const httpService = {
getData: function(url, params) {
return $.ajax({ url: url, method: 'GET', data: params });
}
};
httpService.getData('/test-url', { userId: 1 });
const request = jasmine.Ajax.requests.mostRecent();
expect(request.url).toBe('/test-url');
expect(request.params()).toEqual({ userId: '1' });
});
});
Здесь используется jasmine.Ajax.requests.mostRecent(),
чтобы получить последний отправленный запрос и проверить его
параметры.
Симуляция ответов сервера с использованием Jasmine позволяет легко
тестировать код, который зависит от внешних API, не выполняя реальных
HTTP-запросов. Использование шпионов, моков и дополнительных библиотек,
таких как jasmine-ajax, предоставляет мощные инструменты
для эмуляции серверного взаимодействия, контроля ответов и проверки
правильности работы асинхронных операций.