用EventEmitter覆盖http.request

我正在使用以下function覆盖Node的http.request的fakeweb模块:

 var old_request = http.request; http.request = function(options, callback){ var rule = match_rule(options); if(rule){ var res = new events.EventEmitter(); res.headers = rule.headers || {'Content-Type': 'text/html'}; return {end: function(){ callback(res); res.emit('data', rule.body || ''); res.emit('end'); } }; } else { return old_request.call(http, options, callback); } }; 

我的问题是,我得到的错误:types错误: TypeError: Object #<Object> has no method 'on'从另一个文件中的以下代码:

 var req = proto.request(options, function (res) { ... }); req.on('error', function (err) { err.success = false; settings.complete(err); }); 

我认为我的问题发生是因为它不再是一个EventEmitter ,虽然我可能是错的。 我怎样才能成功覆盖http.request没有得到这个问题?

背景:我正在使用节点版本0.8.2 。 请求NPM是版本2.12.0

更新(2013年2月11日) :我想提供一些关于http.request被调用的更多信息,所以我可以更具体地了解需要什么以及导致错误的原因。 这是所谓的地方:

 var proto = (options.protocol === 'https:') ? https : http; var req = proto.request(options, function (res) { var output = new StringStream(); switch (res.headers['content-encoding']) { case 'gzip': res.pipe(zlib.createGunzip()).pipe(output); break; case 'deflate': res.pipe(zlib.createInflate()).pipe(output); break; default: // Treat as uncompressed string res.pipe(output); break; } output.on('end', function() { if (settings.cookieJar && res.headers['set-cookie']) { var cookies = res.headers['set-cookie']; for (var i = 0; i < cookies.length; i++) { settings.cookieJar.set(cookies[i]); } } if (res.statusCode >= 300 && res.statusCode < 400) { if (settings.maxRedirects > settings.nRedirects++) { // Follow redirect var baseUrl = options.protocol + '//' + ((proxy) ? options.headers['host'] : options.host), location = url.resolve(baseUrl, res.headers['location']); request(location, settings); } else { var err = new Error('Max redirects reached.'); err.success = false; settings.complete(err); } } else if (res.statusCode >= 400) { var err = new Error(output.caught); err.success = false; err.code = res.statusCode; settings.complete(err); } else { settings.complete(null, output.caught, res); } }); }); req.on('error', function (err) { err.success = false; settings.complete(err); }); if (data) { req.write(data); } req.end(); 

编辑

如果你想请求行动完全相同,只是没有应用程序实际上击中请求的服务器,然后尝试使用nock这将拦截您定义的请求,并返回您定义的数据。


原始答案:

我认为你正在寻找的是更像这样的东西:

 var old_request = http.request; http.request = function(options, callback){ var rule = match_rule(options); if(rule){ var res = new events.EventEmitter(), req = new events.EventEmitter(); res.headers = rule.headers || {'Content-Type': 'text/html'}; req.end = function(){ if(callback) callback(res); res.emit('data', rule.body || ''); res.emit('end'); }; return req; } else { return old_request.call(http, options, callback); } };