直到超时 sinon chai 才解决承诺的测试
Testing that promise resolved not until timeout sinon chai
我们有一个简单的等待方法利用节点应用程序中的承诺
exports.wait = (timeout) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve()
}, timeout)
});
};
我们尝试使用 sinon 和 chai 测试此行为。
我们设法使用 chai-as-promised 获得了正确的断言,但它只检查承诺的解决,而我们无法测试真实的行为:
- 将 100 毫秒的值传递给等待方法时
- 我们预计承诺不会在 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: expected false to be 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!
});
详情
Fake timers 将使用 setTimeout
安排的回调转换为同步调用。
另一方面,Promise
回调在 Promise
解析时在 PromiseJobs queue 中排队,并且 运行 直到 在当前执行消息完成后.
在这种情况下,当前运行ning消息是测试,所以then
回调将fulfilled
设置为true
不会 运行 直到 在 测试完成后。
您可以使用 async
测试函数并在任何您想要暂停当前 运行ning 消息并允许任何排队的 Promise
回调的位置调用 await Promise.resolve();
至 运行.
有关将假定时器与 Promises
一起使用的更多详细信息,请参阅使用 Jest
的 ,但概念是相同的。
我们有一个简单的等待方法利用节点应用程序中的承诺
exports.wait = (timeout) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve()
}, timeout)
});
};
我们尝试使用 sinon 和 chai 测试此行为。
我们设法使用 chai-as-promised 获得了正确的断言,但它只检查承诺的解决,而我们无法测试真实的行为:
- 将 100 毫秒的值传递给等待方法时
- 我们预计承诺不会在 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: expected false to be 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!
});
详情
Fake timers 将使用 setTimeout
安排的回调转换为同步调用。
Promise
回调在 Promise
解析时在 PromiseJobs queue 中排队,并且 运行 直到 在当前执行消息完成后.
在这种情况下,当前运行ning消息是测试,所以then
回调将fulfilled
设置为true
不会 运行 直到 在 测试完成后。
您可以使用 async
测试函数并在任何您想要暂停当前 运行ning 消息并允许任何排队的 Promise
回调的位置调用 await Promise.resolve();
至 运行.
有关将假定时器与 Promises
一起使用的更多详细信息,请参阅使用 Jest
的