AssertError: исключено вызываться один раз, но вызывалось 0 раз - PullRequest
0 голосов
/ 09 ноября 2018

Я использую nodejs и sinon.

В настоящее время, когда я запускаю свое приложение, то есть класс UpdateTask, оно работает нормально, даже ошибки.

Однако, когда я приступил к выполнению модульного тестирования, я столкнулся со следующей проблемой.

AssertError: expected updateBook to be called once but was called 0 times

Я не понимаю, почему он называется 0 раз, когда он должен один раз.

Что-то не так сделано в моем коде?

UpdateTask Class:

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 голосов
/ 26 ноября 2018

Выпуск

tempTable.updateBook вызывается во время обратного вызова, который не выполняется к тому времени, когда sinon.assert.calledOnce(getTempTableUpdateSpy); запускается и завершается ошибкой.


Решение

Убедитесь, что у обратного вызова, который вызывает tempTable.updateBook, была возможность запуска перед утверждением.

Это намного проще при использовании Обещаний, когда Обещание можно вернуть и ожидать в тесте. Этот сценарий более сложный, поскольку существуют обратные вызовы и нет чистого способа вернуть то, что можно ожидать.

Важно отметить, что тест будет оставаться активным до истечения времени ожидания или до вызова 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();
});
...