AssertError:预期被调用一次,但被调用0次

时间:2018-11-09 05:33:09

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

1 个答案:

答案 0 :(得分:1)

问题

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