我有一个 expressjs
应用程序,其中包含以下 routes
和 middleware
模块。我正在尝试使用 mocha
、chai
、http-chai
和 sinonjs
测试路由模块。
API 使用 mysql
并且为了测试路由模块,我将它全部模块化以便我可以 stub mysql 模块。
但是,当我尝试 stub middleware/index
时,我遇到了麻烦。如果我尝试正常要求 index
,模块实际上并没有被 stub 。如果我尝试使用 require.cache[require.resolve('./../../lib/routes/middleware/index')];
来要求它,它似乎 stub 了一些东西,但是indexStub.returns(indexObj)
返回错误 TypeError: indexStub.returns is not a function
和 TypeError: indexStub.restore is not a function
。
如何正确地 stub index.js
以控制代码流并防止它尝试连接到 mysql?
路由.js
'use strict';
const express = require('express');
const router = express.Router();
const configs = require('./../config/configs');
const middleware = require('./middleware/index');
const bodyParser = require('body-parser');
const useBodyParserJson = bodyParser.json({
verify: function (req, res, buf, encoding) {
req.rawBody = buf;
}
});
const useBodyParserUrlEncoded = bodyParser.urlencoded({extended: true});
// creates a new post item and return that post in the response
router.post('/posts', useBodyParserUrlEncoded, useBodyParserJson, middleware.validatePostData, middleware.initializeConnection, middleware.saveNewPost, middleware.closeConnection, function(req, res) {
if (res.statusCode === 500) {
return res.send();
}
if (res.statusCode === 405) {
return res.send('Item already exists with slug ' + req.body.slug + '. Invalid method POST');
}
res.json(res.body).end();
});
module.exports = router;
中间件/index.js
'use strict';
const configs = require('./../../config/configs');
const database = require('./../../factories/databases').select(configs.get('STORAGE'));
const dataV = require('./../../modules/utils/data-validator');
module.exports = {
initializeConnection: database.initializeConnection, // start connection with database
closeConnection: database.closeConnection, // close connection with database
saveNewPost: database.saveNewPost, // creates and saves a new post
validatePostData: dataV.validatePostData, // validates user data
};
规范路由.js
'use strict';
var chai = require('chai');
var chaiHttp = require('chai-http');
var sinonChai = require("sinon-chai");
var expect = chai.expect;
var sinon = require('sinon');
chai.use(sinonChai);
chai.use(chaiHttp);
var app = require('./../../app');
describe('COMPLEX ROUTES WITH MIDDLEWARE', function() {
var indexM = require.cache[require.resolve('./../../lib/routes/middleware/index')];
describe('POST - /posts', function() {
var indexStub,
indexObj;
beforeEach(function() {
indexStub = sinon.stub(indexM);
indexObj = {
'initializeConnection': function(req, res, next) {
return next();
},
'closeConnection': function(req, res, next) {
return next();
},
'validatePostData': function(req, res, next) {
return next();
}
};
});
afterEach(function() {
indexStub.restore();
});
it('should return a 500 response', function(done) {
indexObj.saveNewPost = function(req, res, next) {
res.statusCode = 500;
return next();
};
indexStub.returns(indexObj);
chai.request(app)
.post('/posts')
.send({'title': 'Hello', 'subTitle': 'World', 'slug': 'Example', 'readingTime': '2', 'published': false})
.end(function(err, res) {
expect(res).to.have.status(500);
done();
});
});
});
});
最佳答案
您根本不用 Sinon,因为它根本不处理模块加载。我看到您已经开始使用内部 Node API 手动执行此操作,但我建议您按照 we advise in the Sinon docs regarding this usecase 的方式执行此操作: 请使用 proxyquire
。
它使您能够用 require
调用 ./middleware/index.js
来替换您自己喜欢的模拟对象(可能使用 sinon 制作)。
你会像这样使用它:
var myIndex = {
initializeConnection: sinon.stub(),
closeConnection: sinon.stub(),
saveNewPost: sinon.stub()
};
var app = proxyquire('./../../app', {'./middleware/index': myIndex});
关于mysql - nodejs - stub 模块。使用 sinon 导出函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42417962/