我在下面有一个restify动作代码块:
function retriveAll(req, res, next) {
db.user
.find({where: {id: 1})
.then(function(user){
res.send(user);
})
.catch(function(details){
res.send(details.message);
})
.finally(function(){
next();
});
}
我想测试此操作,专门验证在此代码块中调用res.send()。然后验证res.send()返回的数据。我正在使用 SinonJs 和 Mocha 来测试框架。以下是上述方法的示例测试代码块。
describe('retrieveAll()', function() {
reqStub = {};
resStub = {send: sinon.stub()};
nextStub = sinon.stub();
beforeEach(function() {
module.retrieveAll(reqStub, resStub, nextStub);
});
// this doesn't work
// and the sub.calledCount is 0
// i wonder if it's because the res.send() is inside a Promise code block???
// if I move the res.send() out from Promise, just before next(), then it works
it('should call res.send()', function() {
sinon.assert.calledOnce(resStub.send);
});
// this one works
it('should call next', function() {
sinon.assert.calledOnce(nextStub);
});
});
有人可以解释一下吗?
答案 0 :(得分:2)
beforeEach()
的回调函数接收done
参数,可以调用该参数来表示异步完成。由于您的retriveAll
函数调用最后一个参数(next
)作为最后一个操作,因此您可以将该参数作为next
值传递,它应该有效:
beforeEach(function(done) {
module.retrieveAll(reqStub, resStub, done);
});
但是你会松开nextStub
,所以......或者,你可以<{1}}函数间谍:
done
答案 1 :(得分:1)
所以,我感谢 @Amit 指导我done
上的beforeEach
回调
首先,我修改了retrieveAll
,因此next
回调包含在承诺链中。我把它放在finally
处理程序中,确保在所有进程后调用next
。
第二次,我将done
传递给beforeEach
,然后nextStub
会监视done
回调。
第三次,而不是将done
cb传递给module.v1.retrieveAll
我使用了nextStub
。这解决了测试nextStub.calledOnce
的问题。
现在更新的代码如下:
function retriveAll(req, res, next) {
db.user
.find({where: {id: 1})
.then(function(user){
res.send(user);
})
.catch(function(details){
res.send(details.message);
})
.finally(function(){
next();
});
}
describe('retrieveAll()', function() {
var reqStub = {};
var resStub = {send: sinon.stub()};
var nextStub;
beforeEach(function(done) {
nextStub = sinon.spy(done);
module.retrieveAll(reqStub, resStub, nextStub);
});
// this doesn't work
// and the sub.calledCount is 0
// i wonder if it's because the res.send() is inside a Promise code block???
// if I move the res.send() out from Promise, just before next(), then it works
it('should call res.send()', function() {
sinon.assert.calledOnce(resStub.send);
});
// this one works
it('should call next', function() {
sinon.assert.calledOnce(nextStub);
});
});
我会选择@Amit答案作为最佳答案,因为他帮助并提供了有关变化的线索。