最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Sinon clock.tick doesn't advance time for setTimeout - Stack Overflow

programmeradmin3浏览0评论

I am writing a test for an async function which performs a series of tasks and at one point waits for 60 seconds before doing some more tasks. I am trying to use sinon.useFakeTimers() to skip those 60 seconds so that I can test the logic after the delay.

foo.js

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

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

I tried putting sinon.useFakeTimers(); in various other places, but the Promise doesn't resolve and the stub I pass into foo doesn't get called.

I am writing a test for an async function which performs a series of tasks and at one point waits for 60 seconds before doing some more tasks. I am trying to use sinon.useFakeTimers() to skip those 60 seconds so that I can test the logic after the delay.

foo.js

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

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

I tried putting sinon.useFakeTimers(); in various other places, but the Promise doesn't resolve and the stub I pass into foo doesn't get called.

Share Improve this question asked Apr 29, 2019 at 15:13 MoglumMoglum 1432 silver badges7 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 9

Make your test function async and await a resolved Promise after advancing your clock to give the Promise callback queued by the await in foo a chance to run before doing your assertion:

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

For plete details see my answer here which uses Jest and Jest timer mocks but the concepts are the same and also apply to Mocha and Sinon fake timers.

发布评论

评论列表(0)

  1. 暂无评论