用MochatestingExpress和Mongoose

我正在尝试使用Mocha和Chai来testing我的REST API端点处理程序,该应用程序是使用Express和Mongoose构build的。 我的处理程序主要是这样的forms:

var handler = function (req, res, next) { // Process the request, prepare the variables // Call a Mongoose function Model.operation({'search': 'items'}, function(err, results) { // Process the results, send call next(err) if necessary // Return the object or objects return res.send(results) } } 

例如:

 auth.getUser = function (req, res, next) { // Find the requested user User.findById(req.params.id, function (err, user) { // If there is an error, cascade down if (err) { return next(err); } // If the user was not found, return 404 else if (!user) { return res.status(404).send('The user could not be found'); } // If the user was found else { // Remove the password user = user.toObject(); delete user.password; // If the user is not the authenticated user, remove the email if (!(req.isAuthenticated() && (req.user.username === user.username))) { delete user.email; } // Return the user return res.send(user); } }); }; 

这个问题是函数返回,因为它调用Mongoose方法和testing用例如下所示:

 it('Should create a user', function () { auth.createUser(request, response); var data = JSON.parse(response._getData()); data.username.should.equal('some_user'); }); 

在做任何事情之前,不要在函数返回时通过。 Mongoose使用Mockgoose来模拟,请求和响应对象被Express-Mocks-HTTP模拟。

虽然使用superagent和其他请求库是相当普遍的,但我宁愿单独testing这些函数,而不是testing整个框架。

有没有办法让testing在评估应用语句之前等待,而不改变我testing的代码来返回承诺?

你应该使用一个testing的asynchronous版本,通过提供一个带有done参数的函数。

有关更多详细信息,请参阅http://mochajs.org/#asynchronous-code

既然你不想修改你的代码,那么一种方法就是在testing中使用setTimeout来等待调用完成。

我会尝试这样的事情:

 it('Should create a user', function (done) { auth.createUser(request, response); setTimeout(function(){ var data = JSON.parse(response._getData()); data.username.should.equal('some_user'); done(); }, 1000); // waiting one second to perform the test }); 

可能有更好的办法

显然,express-mocks-http刚刚被放弃,而新的代码在node-mocks-http下。 使用这个新库,可以做我想要使用的事件。 它没有logging,但看着你可以弄明白的代码。

在创build响应对象时,您必须传递EventEmitter对象:

 var EventEmitter = require('events').EventEmitter; var response = NodeMocks.createResponse({eventEmitter: EventEmitter}); 

然后,在testing中,您将为侦听器添加事件“end”或“send”,因为在调用res.send时,触发器都将被触发。 如果您的调用不是res.send(例如,res.status(404).end(),则'end'涵盖的不仅仅是'send'。

testing看起来像这样:

 it('Should return the user after creation', function (done) { auth.createUser(request, response); response.on('send', function () { var data = response._getData(); data.username.should.equal('someone'); data.email.should.equal('asdf2@asdf.com'); done(); }); });