Mock Clock — это инструмент в Jasmine, позволяющий
контролировать время в тестах, симулируя работу таймеров
(setTimeout, setInterval, Date)
без необходимости реального ожидания. Он используется для ускорения
тестов и повышения их предсказуемости, особенно когда требуется проверка
асинхронного кода, зависящего от времени.
Для работы с mock clock используется метод
jasmine.clock(). Основные шаги:
beforeEach(function() {
jasmine.clock().install();
});
afterEach(function() {
jasmine.clock().uninstall();
});
Методы install() и uninstall() гарантируют,
что mock clock активен только на время конкретного теста, предотвращая
влияние на другие тесты.
const baseTime = new Date(2026, 0, 11);
jasmine.clock().mockDate(baseTime);
Все вызовы new Date() будут возвращать это значение, что
обеспечивает предсказуемость тестов, зависящих от времени.
После установки mock clock стандартные таймеры становятся управляемыми:
let result = false;
setTimeout(() => { result = true; }, 1000);
jasmine.clock().tick(1000); // имитация 1000 мс
console.log(result); // true
Метод tick(ms) ускоряет время на указанное количество
миллисекунд, вызывая все таймеры, срок которых истек.
let counter = 0;
setInterval(() => { counter++; }, 500);
jasmine.clock().tick(1500);
console.log(counter); // 3
Каждый интервал выполняется столько раз, сколько раз уложилось в
указанное время при tick.
Для тестирования промисов и асинхронных операций mock clock может
использоваться в сочетании с done колбэком:
it("должен изменять состояние через 1 секунду", function(done) {
let status = false;
setTimeout(() => { status = true; }, 1000);
jasmine.clock().tick(1000);
expect(status).toBeTrue();
done();
});
Важно помнить, что mock clock не управляет
промисами, созданными через
Promise.resolve().then(...), так как они обрабатываются
микротасками вне таймеров. Для таких случаев используют либо реальные
таймеры, либо дополнительные методы синхронизации.
Метод mockDate позволяет фиксировать время, что полезно
для тестов, зависящих от системного времени:
const fixedDate = new Date(2026, 0, 11, 12, 0, 0);
jasmine.clock().mockDate(fixedDate);
expect(new Date().getHours()).toBe(12);
Это предотвращает непредсказуемое поведение, если тесты выполняются в разное время суток или в разных часовых поясах.
Jasmine позволяет комбинировать mock clock с spyOn для
отслеживания вызовов функций внутри таймеров:
const callback = jasmine.createSpy("callback");
setTimeout(callback, 1000);
jasmine.clock().tick(1000);
expect(callback).toHaveBeenCalled();
Такой подход упрощает проверку, что определенные функции вызываются через заданный интервал времени, без реальной задержки.
Promise.then и async/await не управляются
jasmine.clock(). Для их тестирования требуется отдельное
ожидание через done или использование
async/await с реальными таймерами.uninstall() в
afterEach, иначе mock clock может «утечь» в другие
тесты, вызывая неожиданное поведение.Mock clock особенно эффективен в следующих сценариях:
setInterval.Использование mock clock повышает детерминированность тестов, делает их быстрее и устойчивыми к случайным задержкам, что критично при CI/CD.