Jest предоставляет утилиты для тестирования функций на основе таймера, таких как setTimeout
или setInterval
. Для этого используется функция jest.useFakeTimers()
, которая заменяет нативные функции таймера на имитации, контролируемые Jest.
Тестирование setTimeout
:
- Используйте
jest.useFakeTimers()
: Это позволяет Jest контролировать таймеры. - Вызовите функцию, которую хотите протестировать.
- Используйте
jest.runAllTimers()
: Это быстро продвигает время и выполняет все ожидающие обратные вызовы таймера немедленно. - Утвердите, что ваша функция вела себя так, как ожидалось.
Предположим, у вас есть функция, которая использует setTimeout
:
function delayedGreeting(callback) {
setTimeout(() => {
callback('Hello, world!');
}, 1000);
}
Теперь вы можете написать тест для этой функции:
test('delayedGreeting calls callback after 1 second', () => {
jest.useFakeTimers();
const callback = jest.fn();
delayedGreeting(callback);
// На этом этапе таймер еще не выполнен
expect(callback).not.toHaveBeenCalled();
// Продвигаем время на 1 секунду
jest.runAllTimers();
// Теперь таймер выполнен, и обратный вызов должен быть вызван
expect(callback).toHaveBeenCalledWith('Hello, world!');
});
Тестирование setInterval
:
Процесс аналогичен, но вместо jest.runAllTimers()
используйте jest.advanceTimersByTime(ms)
, где ms
— это интервал времени в миллисекундах. Это продвигает таймеры на указанное время и выполняет любые обратные вызовы, запланированные в это время.
Предположим, у вас есть функция, которая использует setInterval
:
function periodicGreeting(callback) {
setInterval(() => {
callback('Hello, world!');
}, 1000);
}
Теперь вы можете написать тест для этой функции:
test('periodicGreeting calls callback every second', () => {
jest.useFakeTimers();
const callback = jest.fn();
periodicGreeting(callback);
// На этом этапе таймер еще не выполнен
expect(callback).not.toHaveBeenCalled();
// Продвигаем время на 1 секунду
jest.advanceTimersByTime(1000);
// Теперь таймер выполнен, и обратный вызов должен быть вызван
expect(callback).toHaveBeenCalledWith('Hello, world!');
// Продвигаем время еще на 1 секунду
jest.advanceTimersByTime(1000);
// Теперь таймер выполнен второй раз
expect(callback).toHaveBeenCalledTimes(2);
});
Пояснение:
- Использование
jest.useFakeTimers()
: Имитирует таймеры, позволяя Jest контролировать их. - Вызов функции: Вызываем функцию, которую хотим протестировать.
- Продвижение времени: Используем
jest.runAllTimers()
дляsetTimeout
илиjest.advanceTimersByTime(ms)
дляsetInterval
, чтобы продвинуть время и выполнить обратные вызовы. - Утверждения: Проверяем, что функция вела себя так, как ожидалось.ckeif
Этот подход позволяет вам тестировать функции на основе таймера, гарантируя, что они работают правильно и вызывают обратные вызовы в нужные моменты времени.