我正在使用node.js做一个RESTful api,
使用mocha,sinon,chai进行单元测试。
使用ibm DB2的数据库。
问题:
在上一篇文章here中,我询问了如何模拟pool.open(connString, function (err, db)
。我已经修改了密码。现在我还有其他问题。
问题1:
我正在根据newsController.js对exports.getNews
方法进行单元测试。那么在newsController.spec.js下,方法A是更正确的方法吗?基于我对类似Mockito的单元测试库如何在Java中工作的理解?
问题2:
使用方法A进行测试时,出现此错误消息。
1) News service
should list a SINGLE News /news/newsId GET:
AssertError: expected value to match
expected = {"result":[{"NEWS_ID":999,"TITLE":"TEST","NEWS_TYPE":"2","DESCRIPTION":"MAINTENANCE","CREATED_BY":"PETER","CREATED_DATE":"2018-08-20"}]}
actual = undefined
当我设置了存根的返回值时,它怎么可能不确定?
问题3
我可以正确进行req.params.newsId
测试吗?
代码:
这些是已经正确运行的文件。
newsRest.js:
module.exports = (app) => {
const controller = require('../controller/newsController');
app.route('news/:newsId').get(controller.getNews);
};
newsController.js:
'use strict';
//imports
var connectionString = require('../common/ibmdb2Pool').connectionString;
var connString = connectionString();
var initPool = require('../common/ibmdb2Pool').initPool;
var pool = initPool();
const query = require('../db/query');
/*
* Restful API starts here
* */
//get news by id
exports.getNews = (req, res) => {
//get from request
const newsId = req.params.newsId;
const params = [newsId];
pool.open(connString, function (err, db) {
if (err) {
return console.log(err);
}
db.query(query.sqlSelect, params, function (error, result, info) {
if (error) {
console.log(error);
return false;
}
res.status(200).json({
result: result
});
});
});
};
ibmdb2Pool.js
'use strict';
//imports
require('dotenv').config();
var Pool = require("ibm_db").Pool;
// access the environment variables for this environment
var connString = process.env.CONNSTRING;
//variables
const minPoolSize = 20;
const maxPoolSize = 100;
//return connection string from environment file.
exports.connectionString = function () {
return connString;
};
//init the db pool with a min and max size
exports.initPool = function () {
var pool = new Pool();
var ret = pool.init(minPoolSize, connString);
if(ret !== true) {
console.log("Cannot init pool. " + ret);
}
pool.setMaxPoolSize(maxPoolSize);
return pool;
};
这是我的单元测试课:
newsController.spec.js
process.env.NODE_ENV = 'test';
var initPool = require('../common/ibmdb2Pool').initPool;
var pool = initPool();
const sinon = require('sinon');
const request = require('request');
const chai = require('chai');
const chaiHttp = require('chai-http');
const should = chai.should();
let server = require('../../../main.js');
chai.use(chaiHttp);
var poolMock;
describe('news service', () => {
const req = httpMocks.createRequest();
var res = httpMocks.createResponse();
var param;
beforeEach(() => {
param = sinon.spy(req, 'param');
poolMock = sinon.stub(pool, 'open').callsArgWith(
1, // argument position
null, // 1st callback argument
{ success: true } // 2d cb argument
);
poolMock.returns(
JSON.stringify(announcements.single.success.body));
});
});
afterEach(() => {
poolMock.restore();
param.restore();
});
it('should list a SINGLE news /news/newsId GET', (done) => {
//Method A
req.params.newsId = 999;
var result = controller.getNews(req, res);
sinon.assert.match(req.params.newsId, 999);
sinon.assert.match(result,
JSON.stringify(news.single.success.body));
//Method B
chai.request(server)
.get('/news/999')
.end(function(err, res){
res.should.have.status(200);
res.should.be.json;
res.body.should.be.a('object');
res.body.result.should.include.keys(
'NEWS_ID', 'TITLE', 'NEWS_TYPE', 'DESCRIPTION', 'CREATED_BY', 'CREATED_DATE'
);
done();
})
});
});