Sinon clock.tick 没有为 setTimeout 提前时间

Sinon clock.tick doesn't advance time for setTimeout

我正在为 async 函数编写测试,该函数执行一系列任务,并在某个时刻等待 60 秒,然后再执行更多任务。我正在尝试使用 sinon.useFakeTimers() 跳过这 60 秒,以便我可以在延迟后测试逻辑。

foo.js

module.exports.foo = async f => {
  // ... more code ...
  await new Promise((resolve, reject) => {
    setTimeout(resolve, 60000);
  });
  // ... more code ...
  f();
  // ... more code ...
};

测试-foo.js

const sinon = require('sinon');
const expect = require('chai').expect;

const { foo } = require('./foo');

describe('Module Foo ', function() {
  it('call function after 1 minute', function() {
    var clock = sinon.useFakeTimers();
    const bar = sinon.stub();

    foo(bar);
    expect(bar.called).to.be.false;
    clock.tick(100000);
    expect(bar.called).to.be.true; // this one fails
  });
});

我尝试将 sinon.useFakeTimers(); 放在其他不同的地方,但是 Promise 没有解析,我传递给 foo 的存根也没有被调用。

让你的测试函数 asyncawait 在提前你的时钟后解决 PromisePromise回调awaitfoo 有机会 运行 在做你的断言之前:

const sinon = require('sinon');
const expect = require('chai').expect;

const { foo } = require('./foo');

describe('Module Foo ', function() {
  it('call function after 1 minute', async function() {  // <= async test function
    var clock = sinon.useFakeTimers();
    const bar = sinon.stub();

    foo(bar);
    expect(bar.called).to.be.false;  // Success!
    clock.tick(100000);
    await Promise.resolve();  // <= give queued Promise callbacks a chance to run
    expect(bar.called).to.be.true;  // Success!
  });
});

有关完整的详细信息,请参阅 which uses Jest and Jest timer mocks but the concepts are the same and also apply to Mocha and Sinon fake timers