promiseDelay returns a Promise that resolves after ms so call a spy in then and test to see if the spy has been called after different intervals:
describe('promiseDelay', () => {
beforeEach(() => { jest.useFakeTimers(); });
afterEach(() => { jest.useRealTimers(); });
test('should not resolve until timeout has elapsed', async () => {
const spy = jest.fn();
promiseDelay(100).then(spy); // <= resolve after 100ms
jest.advanceTimersByTime(20); // <= advance less than 100ms
await Promise.resolve(); // let any pending callbacks in PromiseJobs run
expect(spy).not.toHaveBeenCalled(); // SUCCESS
jest.advanceTimersByTime(80); // <= advance the rest of the time
await Promise.resolve(); // let any pending callbacks in PromiseJobs run
expect(spy).toHaveBeenCalled(); // SUCCESS
});
});
Note that test code is synchronous and Timer Mocks make setTimeout synchronous but then queues a callback in PromiseJobs so any queued callbacks need to be allowed to run before testing if the spy has been called.
This can be done by using an async test function and calling await on a resolved Promise which effectively queues the rest of the test at the end of PromiseJobs allowing any pending callbacks to run before the test continues.
Additional information about how promises and fake timers interact is available in my answer here.