javascript - 直到超时才解决承诺的测试 sinon chai
问题描述
我们有一个简单的等待方法,在我们的节点应用程序中利用 Promise
exports.wait = (timeout) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve()
}, timeout)
});
};
我们尝试使用 sinon 和 chai 来测试这种行为。
我们设法使用 chai-as-promised 获得了正确的断言,但它只检查承诺的解决,而无法让我们测试真实的行为:
- 将 100 ms 的值传递给 wait 方法时
- 我们预计承诺不会在 99 毫秒内解决
- 我们预计承诺会在 100 毫秒内解决
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:预期 false 为 true
那么如何在 chai - sinon 下将计时器与 promise 测试结合起来,以正确地利用我们的定时解决方案?
解决方案
您可以像这样测试问题中的代码:
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!
});
细节
假计时器将调度的回调setTimeout
转换为同步调用。
Promise
另一方面,回调在解决时在PromiseJobs 队列中排队,并且在当前正在执行的消息完成Promise
之前不会运行。
在这种情况下,当前正在运行的消息是test,因此设置为的then
回调在测试完成之前不会运行。fulfilled
true
您可以使用async
测试函数并await Promise.resolve();
在要暂停当前正在运行的消息并允许任何排队Promise
的回调运行的任何时候调用。
有关使用 Fake Timers 的更多详细信息,Promises
请参阅this answer which uses Jest
,但概念是相同的。
推荐阅读
- html - 仅在 Firefox 中内容后的空格
- r - DT 代理不显示数据
- python - PM4Py - 生成的图缺乏节点和边权重强调
- angular - Angular 模板驱动表单中的 Karma-Jasmine 测试注册表单
- javascript - 从字符串创建函数
- java - 数学运算出错
- javascript - 将 popup.js 连接到 chrome 扩展中的 content.js 的问题
- r - 使用绝对值缩放填充渐变
- typescript - 如何在 Vue 应用程序中声明全局可用的打字稿接口
- django - 我可以在代理模型中覆盖 ForeignKey 的 related_name 吗?