node.js - AssertError:预期调用一次,但调用了 0 次
问题描述
我正在使用 nodejs 和 sinon。
当前,当我运行我的应用程序(即 UpdateTask 类)时,它工作正常,甚至出现错误。
但是,当我开始进行单元测试时,我遇到了以下问题。
AssertError: expected updateBook to be called once but was called 0 times
我不明白为什么它应该被调用 0 次。
我在代码中做错了什么吗?
更新任务类:
function updateInfo() {
let updateCountParams = [];
let updateParams = [];
let idsToUpdateList = null;
tempTable.getBookForUpdateCount(updateCountParams, function (results) {
if (results[0].RECCOUNT > 0) {
tempTable.getBookForUpdate(updateParams, function (results) {
idsToUpdateList = results;
for (var i = 0; i < idsToUpdateList.length; i++) {
let id = idsToUpdateList[i].id;
let param = [];
param.push(id);
let request = api.sendRequest(id);
// Invoke asynchronous call
request
.buffer(true)
.end(function (err, res) {
if (err) {
tempTable.updateBook(param, function (updateBookResult) {
});
return console.error(err.status + " - " + err.message);
}
let data = {
body: res.body,
text: res.text
};
let bkData = data.text;
if (bkData == undefined || bkData == null) {
tempTable.updateBook(param, function (updateBookResult) {
});
return console.error("DATA NOT FOUND".red);
}
//success flow business logic here
...
}); //end asynchronous call
}
});
}
else {
//no record to be processed.
return;
}
});
}
测试用例:
describe('Update Task', () => {
beforeEach(() => {
});
afterEach(() => {
sinon.restore();
});
it('3. API Call - Errror: 404 - Not found', (done) => {
let getTempTableForUpdateCountSpy = sinon.stub(TempTableDao, "getBookForUpdateCount").yields(jsonResult.count.success.result);
let getTempTableForUpdateSpy = sinon.stub(TempTableDao, "getBookForUpdate").yields(jsonResult.single.failure.result);
let getTempTableUpdateSpy = sinon.stub(TempTableDao, "updateBook");
let test = nock('https://test.api.com/id')
.get('/ID125125/')
.reply(404, {
});
updateTask.updateInfo();
sinon.assert.calledOnce(getTempTableForUpdateCountSpy);
sinon.assert.calledOnce(getTempTableForUpdateSpy);
test.interceptors[0].statusCode.should.be.equal(404);
sinon.assert.calledOnce(getTempTableUpdateSpy);
done();
});
解决方案
问题
tempTable.updateBook
sinon.assert.calledOnce(getTempTableUpdateSpy);
在未按时间运行并失败的回调期间调用。
解决方案
确保调用的回调tempTable.updateBook
在断言之前有机会运行。
这在使用 Promise 时要容易得多,因为 Promise 可以在测试中返回和等待。这种情况比较棘手,因为有回调并且没有干净的方法来返回可以等待的东西。
需要注意的重要一点是,测试将保持活动状态,直到超时或被done
调用。
在这种情况下,它看起来updateBook
是代码中发生的最后一件事,也是需要测试的最后一件事。对于这样的场景,可以为存根和断言提供一个模拟实现,然后done
在模拟实现中调用。
这是一个简化的示例:
import * as sinon from 'sinon';
const tempTable = {
updateBook: () => {}
};
const updateInfo = () => {
setTimeout(() => { tempTable.updateBook(); }, 0); // simulate an asynchronous callback
}
test('updateInfo', (done) => {
const spy = sinon.stub(tempTable, 'updateBook');
spy.callsFake(() => {
sinon.assert.calledOnce(spy); // SUCCESS
done();
});
updateInfo();
});
在您的情况下,您可以执行以下操作:
it('3. API Call - Errror: 404 - Not found', (done) => {
let getTempTableForUpdateCountSpy = sinon.stub(TempTableDao, "getBookForUpdateCount").yields(jsonResult.count.success.result);
let getTempTableForUpdateSpy = sinon.stub(TempTableDao, "getBookForUpdate").yields(jsonResult.single.failure.result);
let getTempTableUpdateSpy = sinon.stub(TempTableDao, "updateBook");
let test = nock('https://test.api.com/id')
.get('/ID125125/')
.reply(404, {
});
getTempTableUpdateSpy.callsFake(() => {
sinon.assert.calledOnce(getTempTableForUpdateCountSpy);
sinon.assert.calledOnce(getTempTableForUpdateSpy);
test.interceptors[0].statusCode.should.be.equal(404);
sinon.assert.calledOnce(getTempTableUpdateSpy);
done();
});
updateTask.updateInfo();
});
推荐阅读
- python - Python Pandas - 如何将 df 中的列值与另一个 df 的列值进行比较
- javascript - 如何在开发人员控制台日志中修复此 ajax 错误
- parallel-processing - CI/CD 管道中的并行性,例如 GitHub Actions
- java - 如何在 JTextPane 中放置双倍宽度和双倍高度字符?
- node.js - 嵌套对象数组的 MongoDB 查询优化
- flutter - 在颤动中将故事项目更改为动态小部件
- javascript - 无法使用 Material-UI Drawer 为页面创建页脚
- html - CSS跨度网格调整大小?
- python - Django静态文件未显示
- jmeter - 在JMeter中随机提取JSR223后处理器中的对应值