我如何通过玩笑来测试承诺延迟?

时间:2018-10-05 21:51:23

标签: javascript ecmascript-6 jestjs es6-promise babel-jest

这是我用来延迟处理(用于退避)的代码

export function promiseDelay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

我想测试一下,但无法测试。我曾尝试过与fakeTimers合作,但我的测试永无止境。

test('promiseDelay delays for 1s', async (done) => {
    jest.useFakeTimers();
    Promise.resolve().then(() => jest.advanceTimersByTime(100));
    await promiseDelay(100);
  });

2 个答案:

答案 0 :(得分:2)

promiseDelay返回一个Promise,该地址在ms之后解析,因此在spy中调用then,然后测试一下spy是否已在不同的间隔后调用:

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
  });

});

请注意,测试代码是同步的,Timer Mocks使setTimeout同步,但then queues a callback in PromiseJobs是同步的,因此在测试{{1 }}已被调用。

这可以通过使用spy测试函数并在已解决的async上调用await来完成,该操作有效地将其余测试排入Promise的结尾,从而允许在测试继续之前要运行的所有待处理的回调。

我的答案here中提供了有关承诺和虚假计时器如何交互的其他信息。

答案 1 :(得分:0)

我认为您只需要从函数中返回承诺即可

test('promiseDelay delays for 1s',() => {
  jest.useFakeTimers();
  return Promise.resolve().then(() => jest.advanceTimersByTime(100));
});

,然后侦听一次setTimeout。