как заглушить результат обратного вызова в Sinon? - PullRequest
0 голосов
/ 02 октября 2018

Я новичок в nodejs.

Как заблокировать мой возвращаемый результат, который является обратным вызовом.

Я знаю, что при тестировании не должен получать доступ к БД.

Я выполняю модульное тестирование на уровне контроллера.

Вот мой пример того, как я собираюсь сделать свой тест, основываясь на моем понимании из Java.

  1. Ложный запрос и ответ.
  2. Установить параметр запроса.
  3. Ложный bookDAO.selectBook, чтобы он возвращал определенный пользователем результат.Таким образом, не вызывая DB.
  4. Проверьте / подтвердите значение возвращаемых результатов.(т.е. Ответ должен быть 200, формат JSON, должен иметь столбец BOOK_ID, BOOK_TITLE и т. д.)

Однако я не смог успешно смоделировать свою функцию.После запуска теста npm я получаю эту ошибку.

2018-10-02T10:00:17.809   1) Book service
       1. should list a SINGLE Book /book/id GET:
     Error: selectBook cannot yield to '[object Object]' since no callback was passed. Received [XCV1234, function (result) {

                res.status(200).json({
                        message: format(message.DEFAULT_MSG, "GET", constant.MODULE_URL),
                        result: result
                });
        }]
      at throwYieldError (node_modules\sinon\lib\sinon\call.js:22:11)
      at Object.yieldToOn (node_modules\sinon\lib\sinon\call.js:167:13)
      at Object.yieldTo (node_modules\sinon\lib\sinon\call.js:156:31)
      at Function.spyApi.(anonymous function) [as yieldTo] (node_modules\sinon\lib\sinon\spy.js:416:61)
      at Context.it (test\controller\BookController.spec.js:47:17)

Правильно ли я это делаю?как вернуть результат обратного вызова?


bookController.js:

exports.getBook = (req, res) => {   

    //get from request
    const id = req.params.id;

    const params = [id];

    bookDao.selectBook(params, function (result) {

        res.status(200).json({
            message: format(message.DEFAULT_MSG, "GET", constant.MODULE_URL),
            result: result  
        });
    });
};

bookDao.js:

function selectBook(params, callback) {

    pool.open(connString, function (err, conn) {

        conn.queryResult(query.SQL_SELECT, params, function (err, result) {

            if (err) {
                console.error(err);
                return conn.closeSync();
            }

            var data = result.fetchAllSync();

            // only when successful then call closeSync
            result.closeSync(); 

            return callback(data);
        });

        conn.close();
    });
}

bookRest.js:

module.exports = (app) => {

    // map to controller
    const controller = require('../controller/bookController');

    app.route(constant.MODULE_URL + '/:id').get(controller.getbook);

    app.route(constant.MODULE_URL).put(controller.updateBooks);
};

bookController.spec.js:

process.env.NODE_ENV = 'test';

const sinon = require('sinon');
const chai = require('chai');
const chaiHttp = require('chai-http');
const should = chai.should();
const httpMocks = require('node-mocks-http');

let server = require('../../../main.js');

const bookController = require('../../../controller/bookController.js');
const bookDao = require('../../../dao/bookDao.js');

chai.use(chaiHttp);

let req = httpMocks.createRequest();
let res = httpMocks.createResponse();

describe('Book service', () => {    
    beforeEach(() => {
    });

    afterEach(() => {
    });

    it('1. should list a SINGLE Book /book/id GET', (done) => {

        req.params.id = "XCV1234";
        const selectbook = sinon.stub(bookDao, "selectbook");

        bookController.getbook(req, res);
        selectbook.yieldTo({BOOK_ID : "XCV1234"});

        res.should.have.status(200);
        res.should.be.json;
        res.body.should.be.a('object');

        res.body.result[0].should.include.keys(
            'BOOK_ID'
        );

        sinon.restore();
        done();
     });    
});

1 Ответ

0 голосов
/ 02 октября 2018

Боюсь, yieldsTo не подходит для этого случая.Основываясь на документации, этот метод предназначен для обратного вызова, который передается как свойство, как в

sinon.stub(jQuery, "ajax").yieldsTo("success", [1, 2, 3]);

jQuery.ajax({
  success: function (data) {
    assertEquals([1, 2, 3], data);
  }
});

. Чтобы решить вашу проблему, мы можем использовать yields, поэтому он будет выглядеть так:

...

// should be stubbed before `getbook` is called
sinon.stub(bookDao, "selectbook").yields({
  BOOK_ID: "XCV1234"
});

bookController.getbook(req, res);

res.should.have.status(200);

...

Надеюсь, это поможет

...