Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js AssertError:需要调用一次,但调用了0次_Node.js_Unit Testing_Sinon - Fatal编程技术网

Node.js AssertError:需要调用一次,但调用了0次

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

我正在使用nodejs和sinon

目前,当我运行我的应用程序,即UpdateTask类时,它工作正常,甚至出现错误

然而,当我开始进行单元测试时,我面临以下问题

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();
    });