【发布时间】:2015-11-17 18:00:37
【问题描述】:
我有一个 MEAN 应用程序,我正在尝试让测试在节点端工作。异步事件包装在承诺中,在控制器中使用。我在测试控制器时失败了:(
我要测试的控制器:
ProjectController.prototype.getAll = function(req, res, next) {
req.dic.subjectRepository
.getById(req.params.subjectId)
.then(function(subject) {
res.json(subject.projects);
}, function(err) {
return res.status(404).send('Subject does not exist.' + err);
});
};
subjectRepository 是我们的数据源,它返回一个承诺(mpromise,因为在后台我们使用的是mongoose,但这不重要):
所以在我们的测试中,我们尝试模拟请求(我们将依赖注入容器从中间件注入到 req)和响应(如果 response.json() 已被我们尝试获取的主题调用,则测试成功) 和我们的主题存储库。我们使用bluebird(尽管我出于沮丧尝试了其他人)为我们嘲笑的subjectRepository创建虚假承诺:
describe('SubjectController', function() {
'use strict';
var Promise = require('bluebird');
it('gets all existing subjects', function() {
// -------------------------------------
// subjectRepository Mock
var subjectRepository = {
getAll: function() {},
};
var subjectPromise = Promise.resolve([
{name: 'test'},
{name: 'test2'},
]);
spyOn(subjectRepository, 'getAll').andReturn(subjectPromise);
// -------------------------------------
// request mock
var req = {
dic: {
subjectRepository: subjectRepository,
},
};
// -------------------------------------
// response mock
var res = {
json: function() {},
send: function() {},
};
spyOn(res, 'json');
// -------------------------------------
// actual test
var subjectController = new (require('../../../private/controllers/SubjectController'))();
subjectController.getAll(req, res);
// this succeeds
expect(subjectRepository.getAll).toHaveBeenCalled();
// this fails
// expect(res.json).toHaveBeenCalled();
});
});
问题:如何让测试在承诺成功后运行expect()?
节点 v0.12
代码在 GitHub 上供任何感兴趣的人使用:https://github.com/mihaeu/fair-projects
也许我应该提到控制器是从路由器调用的:
// router handles only routing
// and controller handles data between view and model (=MVC)
subjectRouter.get('/:subjectId', subjectController.get);
我通过更改控制器来传递承诺来实现这一点,但我不确定这是否是我们想要的。难道没有办法让我的方法发挥作用吗?
it('gets all existing subjects', function(done) {
// ...
var subjectController = new (require('../../../private/controllers/SubjectController'))();
subjectController.getAll(req, res).then(function() {
expect(res.json).toHaveBeenCalledWith(testSubjects); // success
}).finally(done);
expect(subjectRepository.getAll).toHaveBeenCalled(); // success
}
【问题讨论】:
-
非常困难,因为您的
getAll方法不会返回承诺。如果确实如此(就像在您的更新中一样),那应该很容易。
标签: node.js testing jasmine promise bluebird