我们有一个简单的等待方法,可以在节点应用程序中利用promise
exports.wait = (timeout) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve()
}, timeout)
});
};
我们试图使用sinon和chai来测试这种行为。
我们设法使用chai-as-promise获得了正确的断言,但它仅检查了promise的解决方式,而不能让我们测试实际行为:
promise与计时器的结合确实让我们头疼。
这是我们最后的尝试设置:
const chai = require('chai');
const expect = chai.expect;
const sinon = require('sinon');
chai.use(require('sinon-chai'));
const chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
const wait = require('./wait').wait;
var clock;
before(() => {
clock = sinon.useFakeTimers();
});
after(() => {
clock.restore();
})
it('should not resolve until given time', (done) => {
const promise = wait(100);
let fulfilled = false;
promise.then(() => {
fulfilled = true;
done();
});
clock.tick(99);
expect(fulfilled).to.be.false;
clock.tick(2);
expect(fulfilled).to.be.true;
});
但是fulfilled
从未翻转为真,或者至少我们无法阅读。
AssertionError:预期为true
然后如何在chain-sinon下将计时器与承诺测试混合使用,以正确分配我们的定时解决方案?
答案 0 :(得分:1)
您可以从以下问题中测试代码:
const chai = require('chai');
const expect = chai.expect;
const sinon = require('sinon');
const wait = require('./wait').wait;
var clock;
before(() => {
clock = sinon.useFakeTimers();
});
after(() => {
clock.restore();
})
it('should not resolve until given time', async () => { // <= async
const promise = wait(100);
let fulfilled = false;
promise.then(() => {
fulfilled = true;
done();
});
clock.tick(99);
await Promise.resolve(); // let any pending Promise callbacks run
expect(fulfilled).to.be.false; // Success!
clock.tick(2);
await Promise.resolve(); // let any pending Promise callbacks run
expect(fulfilled).to.be.true; // Success!
});
详细信息
Fake timers将按setTimeout
安排的回调转换为同步调用。
Promise
回调在Promise
解析时在PromiseJobs queue中排队,并且直到当前执行的消息完成后才运行< / em>。
在这种情况下,当前正在运行的消息是 test ,因此将then
设置为fulfilled
的{{1}}回调直到 之后,测试完成。
您可以使用true
测试功能并在要暂停当前运行的消息并允许任何排队的async
回调运行的任何时间调用await Promise.resolve();
。
有关将假计时器与Promise
一起使用的其他详细信息,请参见this answer,它使用Promises
,但是概念相同。