Node.js AssertError:需要调用一次,但调用了0次
我正在使用nodejs和sinon 目前,当我运行我的应用程序,即UpdateTask类时,它工作正常,甚至出现错误 然而,当我开始进行单元测试时,我面临以下问题Node.js AssertError:需要调用一次,但调用了0次,node.js,unit-testing,sinon,Node.js,Unit Testing,Sinon,我正在使用nodejs和sinon 目前,当我运行我的应用程序,即UpdateTask类时,它工作正常,甚至出现错误 然而,当我开始进行单元测试时,我面临以下问题 AssertError: expected updateBook to be called once but was called 0 times 我不明白为什么它应该被调用一次,却被调用了0次 我的代码中有什么错误吗 UpdateTask类: function updateInfo() { let updateCount
AssertError: expected updateBook to be called once but was called 0 times
我不明白为什么它应该被调用一次,却被调用了0次
我的代码中有什么错误吗
UpdateTask类:
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;
}
});
}
问题
sinon.assert.calledOnce(getTempTableUpdateSpy)之前未运行的回调期间调用了tentable.updateBook
代码>运行并失败
解决方案
确保调用attreable.updateBook
的回调在断言之前有机会运行
这在使用承诺时要容易得多,因为承诺可以在测试中返回和等待。这种情况更加棘手,因为存在回调,并且没有干净的方法返回可以等待的内容
需要注意的一点是,测试将保持活动状态,直到超时或调用done
在这种情况下,updateBook
似乎是代码中发生的最后一件事,也是需要测试的最后一件事。对于这样的场景,可以为存根和断言提供模拟实现,然后在模拟实现中调用done
以下是一个简化的示例:
import*作为sinon从“sinon”导入;
诱惑常数={
更新本:()=>{}
};
常量更新信息=()=>{
setTimeout(()=>{tetrable.updateBook();},0);//模拟异步回调
}
测试('updateInfo',(完成)=>{
const spy=sinon.stub(诱人的“更新本”);
spy.callsFake(()=>{
sinon.assert.calledOnce(spy);//成功
完成();
});
updateInfo();
});
在您的情况下,您可以这样做:
it('3.API调用-错误:404-未找到',(完成)=>{
让getTempTableForUpdateCountSpy=sinon.stub(试探性DAO,“getBookForUpdateCount”).yields(jsonResult.count.success.result);
让getTempTableForUpdateSpy=sinon.stub(testableDao,“getBookForUpdate”).yields(jsonResult.single.failure.result);
让getTempTableUpdateSpy=sinon.stub(testableDao,“updateBook”);
let test=nock('https://test.api.com/id')
.get('/ID125125/'))
.答复(404{
});
getTempTableUpdateSpy.callsFake(()=>{
sinon.assert.calledOnce(getTempTableForUpdateCountSpy);
sinon.assert.calledOnce(getEmptableforUpdateSpy);
test.interceptors[0].statusCode.should.be.equal(404);
sinon.assert.calledOnce(getEmptableUpdateSpy);
完成();
});
updateTask.updateInfo();
});
jsonResult.count.success.result的价值是什么?@deerawan“RECCOUNT”:1另一种澄清问题的方法是我对代码进行了重构。我通过使回调函数调用我的函数来移除我的回调地狱。
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();
});