如何在 sinon 中存根回调结果?
how to stub callback result in sinon?
我是 nodejs 新手。
如何存根我的 return 结果,这是一个回调。
我知道在做测试时不应该访问数据库。
我正在控制器级别进行单元测试。
这是我根据 java 的理解进行测试的流程。
- 模拟请求和响应。
- 设置请求参数。
- 模拟 bookDAO.selectBook 以便它 return 用户定义的结果。因此不调用 DB.
- 验证/断言 return 结果的值。 (即响应必须是 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)
我做的对吗?我如何 return 回调结果?
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();
});
});
恐怕 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);
...
希望对您有所帮助
我是 nodejs 新手。
如何存根我的 return 结果,这是一个回调。
我知道在做测试时不应该访问数据库。
我正在控制器级别进行单元测试。
这是我根据 java 的理解进行测试的流程。
- 模拟请求和响应。
- 设置请求参数。
- 模拟 bookDAO.selectBook 以便它 return 用户定义的结果。因此不调用 DB.
- 验证/断言 return 结果的值。 (即响应必须是 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)
我做的对吗?我如何 return 回调结果?
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();
});
});
恐怕 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);
...
希望对您有所帮助