我尝试使用Mocha和Chai测试我的REST API端点处理程序,该应用程序是使用Express和Mongoose构建的。我的处理程序大多是以下形式:
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方法时会返回并测试这样的情况:
it('Should create a user', function () {
auth.createUser(request, response);
var data = JSON.parse(response._getData());
data.username.should.equal('some_user');
});
在执行任何操作之前,函数返回时永远不会传递。使用Mockgoose模拟Mongoose,并使用Express-Mocks-HTTP模拟请求和响应对象。
虽然使用superagent和其他请求库是相当普遍的,但我更愿意单独测试函数,而不是测试整个框架。
有没有办法在评估should语句之前让测试等待而不更改代码我测试返回promises?
答案 0 :(得分:1)
您应该使用测试的异步版本,方法是为done
提供一个it
参数的函数。
有关详细信息,请参阅http://mochajs.org/#asynchronous-code。
由于您不想修改代码,因此一种方法是在测试中使用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
});
(可能有更好的方式)
答案 1 :(得分:0)
显然,express-mocks-http不久前被放弃了,新代码在node-mocks-http下。使用这个新库可以做我要求使用事件的事情。它没有记录,但查看代码,你可以弄明白。
创建响应对象时,必须传递EventEmitter对象:
var EventEmitter = require('events').EventEmitter;
var response = NodeMocks.createResponse({eventEmitter: EventEmitter});
然后,在测试中,您将为该事件添加一个监听器' end'或者'发送'因为它们都是在调用res.send时触发的。 '端'如果你有res.send以外的电话(例如,res.status(404).end()。
,则发送超过' send'测试看起来像这样:
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();
});
});