Reputation: 878
I am new to nodejs.
How do I stub my return result which is a callback.
I know that I should not access the DB when doing testing.
I am doing unit testing at the controller level.
Here is my flow on how I going to do my test based on my understanding from java.
However, i was not able to successfully mock my function. After running npm test, this is the error that I am receiving.
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)
Am i doing it the right way? how do i return the callback result ?
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();
});
});
Upvotes: 0
Views: 4742
Reputation: 8443
I'm afraid yieldsTo
is not the appropriate method to use for this case. Based on documentation, this method is intended to target callback that passed as property as in
sinon.stub(jQuery, "ajax").yieldsTo("success", [1, 2, 3]);
jQuery.ajax({
success: function (data) {
assertEquals([1, 2, 3], data);
}
});
To solve your problem, we can use yields
so it will be like:
...
// should be stubbed before `getbook` is called
sinon.stub(bookDao, "selectbook").yields({
BOOK_ID: "XCV1234"
});
bookController.getbook(req, res);
res.should.have.status(200);
...
Hope it helps
Upvotes: 1