我正在学习Node.js并且一直在使用Express.真的很喜欢框架;但是,我无法弄清楚如何为路线编写单元/集成测试.
能够对简单模块进行单元测试很容易,并且已经使用Mocha进行了测试 ; 但是,我的单元测试使用Express失败,因为我传入的响应对象不保留值.
正在测试的路由功能(routes/index.js):
exports.index = function(req, res){
res.render('index', { title: 'Express' })
};
Run Code Online (Sandbox Code Playgroud)
单元测试模块:
var should = require("should")
, routes = require("../routes");
var request = {};
var response = {
viewName: ""
, data : {}
, render: function(view, viewData) {
viewName = view;
data = viewData;
}
};
describe("Routing", function(){
describe("Default Route", function(){
it("should provide the a title and the index view name", function(){
routes.index(request, response);
response.viewName.should.equal("index");
});
});
});
Run Code Online (Sandbox Code Playgroud)
当我运行它时,它失败了"错误:检测到全局泄漏:viewName,data".
我哪里出错,以便我可以让这个工作?
有没有更好的方法让我在这个级别对我的代码进行单元测试?
更新 1.更正了代码片段,因为我最初忘记了"it()".
Ric*_*aca 35
正如其他人在评论中所建议的那样,看起来测试Express控制器的规范方法是通过supertest.
示例测试可能如下所示:
describe('GET /users', function(){
it('respond with json', function(done){
request(app)
.get('/users')
.set('Accept', 'application/json')
.expect(200)
.end(function(err, res){
if (err) return done(err);
done()
});
})
});
Run Code Online (Sandbox Code Playgroud)
好处:你可以一次性测试你的整个堆栈.
缺点:感觉和行为有点像集成测试.
Lin*_*iel 19
更改您的响应对象:
var response = {
viewName: ""
, data : {}
, render: function(view, viewData) {
this.viewName = view;
this.data = viewData;
}
};
Run Code Online (Sandbox Code Playgroud)
它会奏效.
Ray*_*nos 19
使用express测试HTTP的最简单方法是窃取TJ的http助手
it("should do something", function (done) {
request(app())
.get('/session/new')
.expect('GET', done)
})
Run Code Online (Sandbox Code Playgroud)
如果你想专门测试你的路线对象,那么传入正确的模拟
describe("Default Route", function(){
it("should provide the a title and the index view name", function(done){
routes.index({}, {
render: function (viewName) {
viewName.should.equal("index")
done()
}
})
})
})
Run Code Online (Sandbox Code Playgroud)
Luk*_*e H 18
我得出结论,真正单元测试表达应用程序的唯一方法是在请求处理程序和核心逻辑之间保持很多分离.
因此,您的应用程序逻辑应该位于可以进行required和单元测试的单独模块中,并且对Express Express和Response类的依赖性最小.
然后在请求处理程序中,您需要调用核心逻辑类的适当方法.
一旦我完成了当前应用程序的重组,我就会举一个例子!
我觉得这样的事情?(随意分享要点或评论,我仍然在探索这个).
编辑
这是一个很小的例子,内联.有关更详细的示例,请参阅要点.
/// usercontroller.js
var UserController = {
_database: null,
setDatabase: function(db) { this._database = db; },
findUserByEmail: function(email, callback) {
this._database.collection('usercollection').findOne({ email: email }, callback);
}
};
module.exports = UserController;
/// routes.js
/* GET user by email */
router.get('/:email', function(req, res) {
var UserController = require('./usercontroller');
UserController.setDB(databaseHandleFromSomewhere);
UserController.findUserByEmail(req.params.email, function(err, result) {
if (err) throw err;
res.json(result);
});
});
Run Code Online (Sandbox Code Playgroud)
如果单位测试用快递4注意这个例子来自gjohnson:
var express = require('express');
var request = require('supertest');
var app = express();
var router = express.Router();
router.get('/user', function(req, res){
res.send(200, { name: 'tobi' });
});
app.use(router);
request(app)
.get('/user')
.expect('Content-Type', /json/)
.expect('Content-Length', '15')
.expect(200)
.end(function(err, res){
if (err) throw err;
});
Run Code Online (Sandbox Code Playgroud)