这令人沮丧地令人费解。
我有以下测试夹具:
describe('#post', function(){
var options,
bodyContent,
bodyWriter;
beforeEach(function(){
// setup common objects ...
});
it('should have request body', function(done){
httpHelper.post(options, bodyWriter, function(err, data){
should.not.exist(err);
should.exist(requestData.body);
requestData.body.should.eql(bodyContent);
done();
});
});
// ...
});
现在,这很好用 - 直到我添加另一个测试:
it('should contain path from options arg', function(done){
httpHelper(options, bodyWriter, function(err, data){
should.not.exist(err);
requestData.options.path.should.eql(options.path);
done();
});
});
现在,当我运行灯具时,我得到以下内容:
http
#post
✓ should require options
✓ should have body
1) should have body
✓ should contain path from options arg
我不知道为什么这个测试会运行两次。有什么想法吗?
答案 0 :(得分:1)
感谢@Louis的评论,我能够找出问题所在。我在测试模块中做的一件事就是伪造本机https模块并使用https://github.com/felixge/node-sandboxed-module注入它。问题出在我的假货上。
var fakeHttpsModule = (function(){
var response = new EventEmitter();
response.setEncoding = function(val){ /* no op */ };
var request = function(options, callback) {
requestData.options = options;
callback(response);
return {
write: function(value){
requestData.body += value;
response.emit('data', value);
},
end: function(){
response.emit('end');
},
on: function(event, callback){ /* no op */ }
};
};
return {
request: request
};
})();
问题基于response
对象的范围。通过将其作用于模块,每次测试称为request
方法时,该测试的回调最终会被添加为EventEmitter
的注册。因此,调用此方法的第一个测试之后的每个测试都会得到Done()
被调用多次的错误。
解决方案是简单地移动response
的声明,使其范围限定为request
函数,如下所示。
var fakeHttpsModule = (function(){
var request = function(options, callback) {
requestData.options = options;
var response = new EventEmitter();
response.setEncoding = function(val){ /* no op */ };
callback(response);
return {
write: function(value){
requestData.body += value;
response.emit('data', value);
},
end: function(){
response.emit('end');
},
on: function(event, callback){ /* no op */ }
};
};
return {
request: request
};
})();