В современном JavaScript асинхронные операции часто реализуются через
Promise. Jasmine предоставляет механизмы для тестирования
таких операций, позволяя корректно обрабатывать асинхронность и
проверять результаты после завершения промиса. Основная задача при
тестировании Promise — дождаться его выполнения перед
проверкой ожидаемых значений.
done для асинхронных тестовJasmine позволяет передавать специальную функцию done в
тестовый блок it. Этот метод применяется, когда необходимо
дождаться завершения асинхронного кода.
it('должен вернуть результат после завершения Promise', (done) => {
const asyncFunction = () => Promise.resolve(42);
asyncFunction().then(result => {
expect(result).toBe(42);
done();
});
});
Ключевые моменты:
done сообщает Jasmine, что тест завершен.done() не вызван, тест будет считаться зависшим и
закончится ошибкой по таймауту.done.fail(error) позволяет корректно обработать ошибки
асинхронного кода.it('обрабатывает ошибки Promise', (done) => {
const failingFunction = () => Promise.reject('Ошибка');
failingFunction().catch(error => {
expect(error).toBe('Ошибка');
done();
});
});
Promise из
тестаАльтернативой использованию done является прямой возврат
промиса из блока it. Jasmine дождется его завершения
автоматически.
it('возвращает Promise с результатом', () => {
const asyncFunction = () => Promise.resolve(100);
return asyncFunction().then(result => {
expect(result).toBe(100);
});
});
Преимущества этого подхода:
done.beforeEach и afterEachJasmine поддерживает асинхронные хуки. Если необходимо подготовить
данные или очистить их перед/после теста, можно использовать
done или возвращать Promise.
let data;
beforeEach(() => {
return fetchData().then(response => {
data = response;
});
});
afterEach(() => {
return clearData().then(() => {
data = null;
});
});
it('проверяет данные после fetch', () => {
expect(data).toBeDefined();
});
Особенности:
beforeEach и afterEach могут возвращать
Promise, Jasmine дождется их завершения перед запуском
теста или после него.Для тестирования промисов, которые должны завершаться с ошибкой,
важно корректно обрабатывать catch.
it('генерирует ошибку в Promise', () => {
const failingFunction = () => Promise.reject(new Error('fail'));
return failingFunction().catch(error => {
expect(error.message).toBe('fail');
});
});
Для промисов с async/await проверка ошибок может
выполняться через конструкцию try/catch:
it('async/await: проверка ошибки', async () => {
const failingFunction = () => Promise.reject(new Error('fail'));
try {
await failingFunction();
} catch (error) {
expect(error.message).toBe('fail');
}
});
async/await с JasmineСовременный способ работы с асинхронным кодом —
async/await. Jasmine полностью поддерживает
async функции в тестах и хуках.
it('async/await: проверка результата Promise', async () => {
const asyncFunction = () => Promise.resolve(7);
const result = await asyncFunction();
expect(result).toBe(7);
});
Преимущества async/await:
done.По умолчанию Jasmine ожидает завершения асинхронного кода 5 секунд. Если промис выполняется дольше, тест упадет по таймауту. Время ожидания можно изменить:
it('длинная асинхронная операция', async () => {
const longPromise = () => new Promise(resolve => setTimeout(() => resolve('ok'), 7000));
const result = await longPromise();
expect(result).toBe('ok');
}, 10000); // увеличенный таймаут до 10 секунд
Иногда необходимо дождаться нескольких промисов одновременно. В
Jasmine это удобно делать через Promise.all.
it('ожидает несколько промисов', async () => {
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const results = await Promise.all([p1, p2]);
expect(results).toEqual([1, 2]);
});
Использование Promise.allSettled позволяет проверять
результаты независимо от того, завершились ли промисы успешно или с
ошибкой.
Jasmine позволяет создавать шпионы (spyOn) для
асинхронных методов. При работе с промисами можно возвращать промис
через and.returnValue.
const api = {
fetchData: () => Promise.resolve('data')
};
spyOn(api, 'fetchData').and.returnValue(Promise.resolve('mockData'));
it('шпион возвращает промис', async () => {
const result = await api.fetchData();
expect(result).toBe('mockData');
});
Особенности:
and.callFake для имитации
асинхронного поведения с разными сценариями.async/await вместо
done — код читается проще.try/catch или .catch на промисах.Promise.all или Promise.allSettled
обеспечивают согласованное ожидание.Эти методы позволяют строить стабильные и предсказуемые тесты асинхронного кода в Jasmine, обеспечивая корректную проверку результатов и обработку ошибок.