javascript - 如果方法在超时后被重复调用如何在sinon中测试
问题描述
我有一个在 setTimeout 之后调用自身的方法 start。它检查它是否有记录,如果没有找到记录,则调整超时。如果它反复调用,我想在 sinon 中测试它。
这是代码正在做的事情,这是一个监听记录是否处于活动状态的过程。该fetchAndMarkRecordAsActive
方法从数据库中获取一条记录,然后重复该方法本身,如果没有找到记录,它将超时更改为大约一个小时的更长超时。但如果记录仍在获取超时仍然默认约 10 分钟。
ProcessReader.prototype.start = function () {
const self = this;
this.fetchAndMarkRecordAsActive(function (error) {
if (error === 'NO_RECORD_FOUND') {
self.timeout = self.longTimeout;
}
setTimeout(function () {
self.start();
}, self.timeout);
});
}
我应该如何使用 sinon 进行测试?
以下是我想要实现的测试用例:
- 它应该在超时后调用自己
- 如果找到记录,它应该重复调用
任何帮助表示赞赏。
更新:
更改this.longTimeout
为self.longTimeout
。我的错
解决方案
这应该让你开始:
const sinon = require('sinon');
describe('ProcessReader', () => {
let startSpy;
let fetchStub;
let clock;
beforeEach(() => {
startSpy = sinon.spy(ProcessReader.prototype, 'start');
fetchStub = sinon.stub(ProcessReader.prototype, 'fetchAndMarkRecordAsActive');
clock = sinon.useFakeTimers();
});
afterEach(() => {
startSpy.restore();
fetchStub.restore();
clock.restore();
});
it('should work as expected', () => {
const reader = new ProcessReader();
fetchStub.yields(); // simulate records returned
reader.start();
sinon.assert.callCount(startSpy, 1); // 1
sinon.assert.callCount(fetchStub, 1); // 1
clock.tick(300000); // wait half the timeout
sinon.assert.callCount(startSpy, 1); // still 1
sinon.assert.callCount(fetchStub, 1); // still 1
clock.tick(300000); // wait the other half
sinon.assert.callCount(startSpy, 2); // 2
sinon.assert.callCount(fetchStub, 2); // 2
clock.tick(600000); // wait the timeout
sinon.assert.callCount(startSpy, 3); // 3
sinon.assert.callCount(fetchStub, 3); // 3
fetchStub.yields('NO_RECORD_FOUND'); // now simulate end of records
clock.tick(600000); // wait the timeout
sinon.assert.callCount(startSpy, 4); // 4
sinon.assert.callCount(fetchStub, 4); // 4
clock.tick(600000); // wait the timeout
sinon.assert.callCount(startSpy, 4); // still 4
sinon.assert.callCount(fetchStub, 4); // still 4
clock.tick(3000000); // wait the rest of longTimeout
sinon.assert.callCount(startSpy, 5); // 5
sinon.assert.callCount(fetchStub, 5); // 5
clock.tick(3600000); // wait longTimeout
sinon.assert.callCount(startSpy, 6); // 6
sinon.assert.callCount(fetchStub, 6); // 6
});
});
请注意,您还应该使用self
来访问longTimeout
.
这里是我用来创建上述测试的代码供参考:
const ProcessReader = function () {
this.longTimeout = 3600000;
this.timeout = 600000;
}
ProcessReader.prototype.fetchAndMarkRecordAsActive = function () { }
ProcessReader.prototype.start = function () {
const self = this;
this.fetchAndMarkRecordAsActive(function (error) {
if (error === 'NO_RECORD_FOUND') {
self.timeout = self.longTimeout; // <= use self.longTimeout
}
setTimeout(function () {
self.start();
}, self.timeout);
});
}
推荐阅读
- batch-file - 备份单个文件并覆盖,如果它存在于 Windows 中的批处理文件
- php - 避免在返回两个方法时使用 if else 语句
- javascript - Mapbox 底图图层之间的过渡
- php - WooCommerce PDF 产品凭证 - 显示 order_created_date?
- reactjs - 在reactjs中单击上传文件时无法显示选择文件的弹出窗口?
- r - 如何比较两个独立组的两个相关值?
- javascript - 如何在javascript中获取两个值或节点之间的差异
- javascript - autoML 无法使用 google cli 命令下载模型
- julia - 从匿名函数访问另一个函数的参数
- python - Python正则表达式用一个或多个单词验证名称?