nock / nock Goto Github PK
View Code? Open in Web Editor NEWHTTP server mocking and expectations library for Node.js
License: MIT License
HTTP server mocking and expectations library for Node.js
License: MIT License
When simply calling
nock = require 'nock'
nock.recorder.rec()
When I run my tests I get:
TypeError: Cannot call method 'apply' of undefined
This is line 64 of recorder.js and is due to the callback function being undefined.
This is a strange error, has anyone seen it before?
Is this possible? We need this to transition away from mock-request
to nock
in jitsu
.
It seems like with this:
30b8308
json bodies can now be specified. However, the recordings still use strings for them. Example:
nock('https://management.core.windows.net:443')
.get('/db1ab6f0-4769-4b27-930e-01e2ef9c123c/services/mobileservices/mobileservices/clitest67f3e332-a60c-436c-a459-232827f16732/scheduler/jobs/foobar')
.reply(200, "{"appName":"clitest67f3e332-a60c-436c-a459-232827f16732","name":"foobar","status":"disabled","intervalUnit":"minute","intervalPeriod":15,"startTime":"2013-04-02T18:46:54.897Z"}", { 'cache-control': 'no-cache',
pragma: 'no-cache',
'content-length': '176',
'content-type': 'application/json; charset=utf-8',
expires: '-1',
server: '33.0.6198.21 (rd_rdfe_stable.130329-1122) Microsoft-HTTPAPI/2.0',
'x-ms-servedbyregion': 'ussouth',
'x-aspnet-version': '4.0.30319',
'x-powered-by': 'ASP.NET',
'x-ms-request-id': 'a72aa96c2fa247c5a3e2fca1719475af',
date: 'Tue, 02 Apr 2013 18:47:04 GMT' });
return result; },
What happens is that now the matching is broken. Seems like the issue is in the new match_body file.
When invoked with:
== body ==
type: string
value: {"intervalPeriod":2,"intervalUnit":"hour","startTime":"2013-04-02T18:46:54.897Z","status":"enabled"}
== spec ==
type: string
value: {"intervalPeriod":2,"intervalUnit":"hour","startTime":"2013-04-02T18:46:54.897Z","status":"enabled"}
It returns false :-/
And consequently, the test run gives:
Nock: No match for HTTP request PUT /db1ab6f0-4769-4b27-930e-01e2ef9c123c/services/mobileservices/mobileservices/clitest67f3e332-a60c-436c-a459-232827f16732/scheduler/jobs/foobar {"intervalPeriod":2,"intervalUnit":"hour","startTime":"2013-04-02T18:46:54.897Z","status":"enabled"}
Ideally this method should work properly in this case (Sounds like a bug) and the recordings could be smart enough to use the new json format.
It shouldn't be required to pass response body.
Example:
var scope = nock('http://www.google.com')
.post('/form')
.reply(200);
For example I have 3 calls to the Twitter API for verify_credentials.json
nock('https://api.twitter.com')
.persist()
.get('/1/account/verify_credentials.json')
.replyWithFile(200, __dirname + '/twitter.json');
With the above the first call is correctly intercepted and the other 2 are not intercepted. But if I add the call a second time like so
nock('https://api.twitter.com')
.persist()
.get('/1/account/verify_credentials.json')
.replyWithFile(200, __dirname + '/twitter.json')
.get('/1/account/verify_credentials.json')
.replyWithFile(200, __dirname + '/twitter.json');
Then all 3 calls will be correctly intercepted.
Normal http requests (that are not mocked with nock) have a request.path
property. Requests that get nocked do not have a request.path
property.
The following sample code exhibits the difference between a normal request and a nocked request:
var http = require('http');
var nock = require('nock');
var options = {
host: "www.google.com",
path: "/no/such/path"
};
var httpReq = http.request(options);
var scope = nock("http://www.google.com")
.get("/no/such/path")
.reply(200);
var nockReq = http.request(options);
console.log(httpReq.path); // => "/no/such/path"
console.log(nockReq.path); // => undefined
I'm developing a library to consume an HTTP API. I'm seeing the following error since adding an edge case that requires the usage of http.ClientRequest#setHeader
:
TypeError: Object #<EventEmitter> has no method 'setHeader'
at [object Object].apiCall (/Users/james/Projects/urban-airship/lib/reques
t.js:112:9) at [object Object].get (/Users/james/Projects/urban-airship/lib/request.js
:129:15)
The lines in question:
if (typeof data !== 'undefined') {
encodedData = JSON.stringify(data);
// THE NEXT TWO ARE THE OFFENDING LINES
req.setHeader('content-type', 'application/json');
req.setHeader('content-length', encodedData.length);
req.end(encodedData, 'utf8');
} else {
req.setHeader('content-length', 0);
req.end();
}
Where req
is an instance of http.ClientRequest
.
When you record POST requests (or any other requests with request body), and use req.end(data) to send request data, the recording of the request will contain duplicated request body. For example, if the application calls req.end('ABC')
, the recoding of the request body will be ABCABC
and subsequently will not match the request during playback.
I believe the culprit is in https://github.com/flatiron/nock/blob/master/lib/recorder.js#L86-88. These three lines are redundant, as the subsequent call to oldEnd in https://github.com/flatiron/nock/blob/master/lib/recorder.js#L89 will eventually percolate to the overriden write method anyways.
^
TypeError: Object #<Object> has no method 'head'
Any reason not to support head?
Can't seem to get it working with restify's various clients, but mainly the json client. Below test shows the nock stub working fine with a plain http.request call, but in the second attempt -- using the same url/port and method -- the test hangs when making the request..
http = require('http')
nock = require 'nock'
restify = require 'restify'
describe "Test mocks using nock", ->
it "should hit the mock when doing a POST to google.com using plain http.request", (done) ->
nock.cleanAll()
# nock.recorder.rec()
scope = nock('http://www.google.com:1234')
.post('/')
.reply 200,
hello:'hello world'
id: 1234
req = http.request
host: 'www.google.com'
method: 'POST'
path: '/'
port: 1234
, (res) ->
res.on 'data', (chunk) ->
console.log 'data1: ' + chunk
res.on 'end', () ->
scope.done()
done()
req.end()
it "should hit the mock when doing a POST to google.com using restify json client", (done) ->
# nock.recorder.rec()
nock.cleanAll()
scope = nock('http://www.google.com:1234/')
.defaultReplyHeaders
'Content-Type':'application/json'
.post('/')
.reply 200, { hello: 'hello universe' }
api_client = restify.createJsonClient
url: 'http://www.google.com:1234'
version: '*'
api_client.post '/', (err,req,res,data) ->
console.log 'data: '+ data
scope.done()
done()
console output:
Test mocks using nock
◦ should hit the mock when doing a POST to google.com using plain http.request: data1: {"hello":"hello world","id":1234}
✓ should hit the mock when doing a POST to google.com using plain http.request
1) should hit the mock when doing a POST to google.com using restify json client
✖ 1 of 2 tests failed:
1) Test mocks using nock should hit the mock when doing a POST to google.com using restify json client:
Error: timeout of 4000ms exceeded
at Object.<anonymous> (/usr/local/lib/node_modules/mocha/lib/runnable.js:158:14)
at Timer.list.ontimeout (timers.js:101:19)
I'm trying a simple request, with nock catching, this seems to have broken recently am running Node v0.8.8.
Nock version: "0.13.3"
Request version: "2.11.0"
describe(".status", function() {
it("should fetch the device status", function(done) {
var scope = nock("http://example.com")
.get("/data_request?id=lu_sdata")
.replyWithFile(200, __dirname + "/fixtures/lu_sdata.json");
client.getStatus(function(error, response, result) {
expect(result.model).toBe("MiCasaVerde VeraLite");
done();
});
})
})
Client.prototype.getStatus = function(callback) {
var request_url = this.url + "/data_request?id=lu_sdata";
request({ url: request_url }, function (error, response, body) {
callback(error, response, JSON.parse(body));
});
};
/home/kevin/Source/javascript/vera/node_modules/request/main.js:517
if (response.connection.listeners('error').indexOf(self._parserErrorHandle
^
TypeError: Cannot call method 'listeners' of undefined
at OverridenClientRequest. (/home/kevin/Source/javascriptclient/node_modules/request/main.js:517:29)
at OverridenClientRequest.EventEmitter.emit (events.js:88:17)
at end (/home/kevin/Source/javascript/client/node_modules/nock/lib/request_overrider.js:206:11)
at process.startup.processNextTick.process._tickCallback (node.js:244:9)
nock('nodejsbug.iriscouch.com')
.put('/v061_doc_cha/foobar', '"{\"foo\":\"bar\"}"')
.reply(201, "{\"ok\":true,\"id\":\"foobar\",\"rev\":\"1-4c6114c65e295552ab1019e2b046b10e\"}\n", { server: 'CouchDB/1.1.1 (Erlang OTP/R14B04)',
location: 'http://nodejsbug.iriscouch.com/v061_doc_cha/foobar',
etag: '"1-4c6114c65e295552ab1019e2b046b10e"',
date: 'Fri, 02 Dec 2011 00:34:58 GMT',
'content-type': 'application/json',
'content-length': '69',
'cache-control': 'must-revalidate' });
'"{\"foo\":\"bar\"}"'
should be '{"foo":"bar"}'
When using node v0.4.12 with nock and jasmine-node, I receive the following error:
Stacktrace:
TypeError: Cannot set property headerSent of # which has only a getter
at new OverridenClientRequest (./node_modules/nock/lib/intercept.js:83:22)
at Object.request (./node_modules/nock/lib/intercept.js:138:15)
The single commit in my fork, which checks hasOwnProperty() in OverridenClientRequest, fixes this.
I ran into a problem while trying to use Nock in an existing node.js script that sends a request to a local node server.
I have reduced the problem to the code below. My server is running on localhost:5000.
Executing this will work:
http = require 'http'
options =
host: '127.0.0.1',
port: 5000,
path: '/'
http.get options, (error, reply) ->
console.log error
console.log reply
But from the moment I require Nock, an error raises:
http = require 'http'
nock = require 'nock'
options =
host: '127.0.0.1',
port: 5000,
path: '/'
http.get options, (error, reply) ->
console.log error
console.log reply
events.js:45
throw arguments[1]; // Unhandled 'error' event
^
Error: ENOTFOUND, Domain name not found
at IOWatcher.callback (dns.js:74:15)
The recorder in nock does not output the URL protocol in the generated code when using 'http'. As a result, when trying to reuse the code in tests, and calling .done() on a nock-ed call, the test will fail.
For example, if we record the following call:
var req = http.request({
host: "www.google.com"
, path: '/'
, port: 80
}, function(res) {
// whatever happens here
});
The following code is generated by the nock recorder:
nock('www.google.com:80')
.get('/')
.reply(200, "<!doctype html><html itemscope=\"itemscope\" itemtype=\"http://schema.org/WebPage\"><head><meta content=\"Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for.\" name=\"description\"><meta content=\"noodp\" name=\"robots\"><meta itemprop=\"image\" content=\"/images/google_favicon_128.png\"><title>Google</title><script>(function(){\nwindow.google={kEI:\"HMsEUY7iGc7kigKXlYHQCQ\",getEI:function(a){for(var b;a&&(!a.getAttribute||!(b=a.getAttribute(\"eid\")));)a=a.parentNode;return b||google.kEI},https:function(){return\"https:\"==window.location.protocol},kEXPI:\"17259,18167,39523,39977,4000116,4001569,4001959,4001975,4002001,4002378,4002436,4002523,4002562,4002700,4002858,4002928,4003035,4003053,4003104,4003215,4003225,4003316,4003318,4003335,4003340,4003387,4003437,4003510,4003518,4003654\",kCSI:{e:\"17259,18167,39523,39977,4000116,4001569,4001959,4001975,4002001,4002378,4002436,4002523,4002562,4002700,4002858,4002928,4003035,4003053,4003104,4003215,4003225,4003316,4003318,4003335,4003340,4003387,4003437,4003510,4003518,4003654\",ei:\"HMsEUY7iGc7kigKXlYHQCQ\"},authuser:0,ml:function(){},kHL:\"en\",time:function(){return(new Date).getTime()},log:function(a,\nb,c,i){var d=new Image,f=google.lc,e=google.li,g=\"\";d.onerror=d.onload=d.onabort=function(){delete f[e]};f[e]=d;!c&&-1==b.search(\"&ei=\")&&(g=\"&ei=\"+google.getEI(i));c=c||\"/gen_204?atyp=i&ct=\"+a+\"&cad=\"+b+g+\"&zx=\"+google.time();a=/^http:/i;a.test(c)&&google.https()?(google.ml(Error(\"GLMM\"),!1,{src:c}),delete f[e]):(d.src=c,google.li=e+1)},lc:[],li:0,Toolbelt:{},y:{},x:function(a,b){google.y[a.id]=[a,b];return!1},load:function(a,b){google.x({id:\"l\"+a},function(){google.load(a,b)})}};\n})();\n(function(){var d=!1;google.sn=\"webhp\";google.timers={};google.startTick=function(a,b){google.timers[a]={t:{start:google.time()},bfr:!!b}};google.tick=function(a,b,h){google.timers[a]||google.startTick(a);google.timers[a].t[b]=h||google.time()};google.startTick(\"load\",!0);\ntry{}catch(e){}})();\nvar _gjwl=location;function _gjuc(){var a=_gjwl.href.indexOf(\"#\");if(0<=a&&(a=_gjwl.href.substring(a),0<a.indexOf(\"&q=\")||0<=a.indexOf(\"#q=\")))if(a=a.substring(1),-1==a.indexOf(\"#\")){for(var d=0;d<a.length;){var b=d;\"&\"==a.charAt(b)&&++b;var c=a.indexOf(\"&\",b);-1==c&&(c=a.length);b=a.substring(b,c);if(0==b.indexOf(\"fp=\"))a=a.substring(0,d)+a.substring(c,a.length),c=d;else if(\"cad=h\"==b)return 0;d=c}_gjwl.href=\"/search?\"+a+\"&cad=h\";return 1}return 0}\nfunction _gjp(){(!window._gjwl.hash||!window._gjuc())&&setTimeout(_gjp,500)};\nwindow._gjp&&_gjp();</script><style>#gbar,#guser{font-size:13px;padding-top:1px !important;}#gbar{height:22px}#guser{padding-bottom:7px !important;text-align:right}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}@media all{.gb1{height:22;margin-right:.5em;vertical-align:top}#gbar{float:left}}a.gb1,a.gb4{text-decoration:underline !important}a.gb1,a.gb4{color:#00c !important}.gbi .gb4{color:#dd8e27 !important}.gbf .gb4{color:#900 !important}</style><style>.h{font-family:arial,sans-serif}body{font-family:arial,sans-serif}td{font-family:arial,sans-serif}a{font-family:arial,sans-serif}p{font-family:arial,sans-serif}body{margin:0;overflow-y:scroll}#gog{padding:3px 8px 0}.h{color:#36c}.q{color:#00c}.ts{border-collapse:collapse}td{line-height:.8em}.gac_m td{line-height:17px}form{margin-bottom:20px}.ts td{padding:0}em{font-weight:bold;font-style:normal}.lst{height:25px;width:496px;font:18px arial,sans-serif}.gsfi{font:18px arial,sans-serif}.gsfs{font:17px arial,sans-serif}.ds{display:inline-box;display: inline-block;margin:3px 0 4px;margin-left:4px}input{font-family:inherit}body{background:#fff;color:black}a.gb1{color:#11c !important}a.gb2{color:#11c !important}a.gb3{color:#11c !important}a.gb4{color:#11c !important}.sblc{padding-top:5px}.lsbb{background:#eee;border:solid 1px;border-color:#ccc #999 #999 #ccc;height:30px}a{color:#11c;text-decoration:none}a:hover{text-decoration:underline}a:active{text-decoration:underline}.fl a{color:#36c}a:visited{color:#551a8b}a.gb1{text-decoration:underline}a.gb4{text-decoration:underline}a.gb3:hover{text-decoration:none}.sblc a{display:block;margin:2px 0;margin-left:13px;font-size:11px}#ghead a.gb2:hover{color:#fff !important}.lsbb{display:block}.ftl{display:inline-block;margin:0 12px}.lsb{background:url(/images/srpr/nav_logo80.png) 0 -258px repeat-x;border:none;color:#000;cursor:pointer;height:30px;margin:0;outline:0;font:15px arial,sans-serif;vertical-align:top}#fll a{display:inline-block;margin:0 12px}.lsb:active{background:#ccc}.lst:focus{outline:none}#addlang a{padding:0 3px}</style><script></script> </head><body dir=\"ltr\" bgcolor=\"#fff\"><script>(function(){var src='/images/srpr/nav_logo80.png';var iesg=false;document.body.onload = function(){window.n && window.n();if (document.images){new Image().src=src;}\nif (!iesg){document.f&&document.f.q.focus();document.gbqf&&document.gbqf.q.focus();}\n}\n})();</script><textarea id=\"csi\" style=\"display:none\"></textarea><div id=\"mngb\"><div id=gbar><nobr><b class=gb1>Search</b> <a class=gb1 href=\"http://www.google.com/imghp?hl=en&tab=wi\">Images</a> <a class=gb1 href=\"http://maps.google.com/maps?hl=en&tab=wl\">Maps</a> <a class=gb1 href=\"https://play.google.com/?hl=en&tab=w8\">Play</a> <a class=gb1 href=\"http://www.youtube.com/?tab=w1\">YouTube</a> <a class=gb1 href=\"http://news.google.com/nwshp?hl=en&tab=wn\">News</a> <a class=gb1 href=\"https://mail.google.com/mail/?tab=wm\">Gmail</a> <a class=gb1 href=\"https://drive.google.com/?tab=wo\">Drive</a> <a class=gb1 style=\"text-decoration:none\" href=\"http://www.google.com/intl/en/options/\"><u>More</u> »</a></nobr></div><div id=guser width=100%><nobr><span id=gbn class=gbi></span><span id=gbf class=gbf></span><span id=gbe></span><a href=\"http://www.google.com/history/optout?hl=en\" class=gb4>Web History</a> | <a href=\"/preferences?hl=en\" class=gb4>Settings</a> | <a target=_top id=gb_70 href=\"https://accounts.google.com/ServiceLogin?hl=en&continue=http://www.google.com/\" class=gb4>Sign in</a></nobr></div><div class=gbh style=left:0></div><div class=gbh style=right:0></div></div><iframe name=\"wgjf\" style=\"display:none\"></iframe><center><br clear=\"all\" id=\"lgpd\"><div id=\"lga\"><img alt=\"Google\" height=\"95\" src=\"/intl/en_ALL/images/srpr/logo1w.png\" width=\"275\" id=\"hplogo\" onload=\"window.lol&&lol()\" style=\"padding:28px 0 14px\"><br><br></div><form action=\"/search\" name=\"f\"><table cellpadding=\"0\" cellspacing=\"0\"><tr valign=\"top\"><td width=\"25%\"> </td><td align=\"center\" nowrap=\"nowrap\"><input name=\"ie\" value=\"ISO-8859-1\" type=\"hidden\"><input value=\"en\" name=\"hl\" type=\"hidden\"><input name=\"source\" type=\"hidden\" value=\"hp\"><div class=\"ds\" style=\"height:32px;margin:4px 0\"><input autocomplete=\"off\" class=\"lst\" value=\"\" title=\"Google Search\" maxlength=\"2048\" name=\"q\" size=\"57\" style=\"color:#000;margin:0;padding:5px 8px 0 6px;vertical-align:top\"></div><br style=\"line-height:0\"><span class=\"ds\"><span class=\"lsbb\"><input class=\"lsb\" value=\"Google Search\" name=\"btnG\" type=\"submit\"></span></span><span class=\"ds\"><span class=\"lsbb\"><input class=\"lsb\" value=\"I'm Feeling Lucky\" name=\"btnI\" type=\"submit\" onclick=\"if(this.form.q.value)this.checked=1; else top.location='/doodles/'\"></span></span></td><td class=\"fl sblc\" align=\"left\" nowrap=\"nowrap\" width=\"25%\"><a href=\"/advanced_search?hl=en&authuser=0\">Advanced search</a><a href=\"/language_tools?hl=en&authuser=0\">Language tools</a></td></tr></table><input type=\"hidden\" id=\"gbv\" name=\"gbv\" value=\"1\"></form><div id=\"gac_scont\"></div><div style=\"font-size:83%;min-height:3.5em\"><br></div><span id=\"footer\"><div style=\"font-size:10pt\"><div id=\"fll\" style=\"margin:19px auto;text-align:center\"><a href=\"/intl/en/ads/\">Advertising Programs</a><a href=\"/services/\">Business Solutions</a><a href=\"https://plus.google.com/116899029375914044550\" rel=\"publisher\">+Google</a><a href=\"/intl/en/about.html\">About Google</a></div></div><p style=\"color:#767676;font-size:8pt\">© 2012 - <a href=\"/intl/en/policies/\">Privacy & Terms</a></p></span></center><div id=xjsd></div><div id=xjsi><script>if(google.y)google.y.first=[];(function(){var b;function c(a){window.setTimeout(function(){var d=document.createElement(\"script\");d.src=a;document.getElementById(\"xjsd\").appendChild(d)},0)}google.dljp=function(a){b=a;google.xjsi||(google.xjsu=a,c(b))};google.dlj=c;})();\nif(!google.xjs){google.dstr=[];google.rein=[];window._=window._||{};window._._DumpException=function(e){throw e};if(google.timers&&google.timers.load.t){google.timers.load.t.xjsls=new Date().getTime();}google.dljp('/xjs/_/js/hp/sb_he,pcc/rt\\x3dj/ver\\x3dib0Fx6HfNdE.en_US./d\\x3d1/sv\\x3d1/rs\\x3dAItRSTPs_I6l2vjvlHM5zh2mZbojMbgtiA');google.xjs=1;}google.pmc={sb:{\"agen\":false,\"cgen\":true,\"client\":\"heirloom-hp\",\"dh\":true,\"ds\":\"\",\"eqch\":true,\"fl\":true,\"host\":\"google.com\",\"jsonp\":true,\"msgs\":{\"lcky\":\"I\\u0026#39;m Feeling Lucky\",\"lml\":\"Learn more\",\"oskt\":\"Input tools\",\"psrc\":\"This search was removed from your \\u003Ca href=\\\"/history\\\"\\u003EWeb History\\u003C/a\\u003E\",\"psrl\":\"Remove\",\"sbit\":\"Search by image\",\"srch\":\"Google Search\"},\"ovr\":{\"l\":1,\"ms\":1},\"pq\":\"\",\"qcpw\":false,\"scd\":10,\"sce\":5,\"stok\":\"_cD49_HpGUcJ5FShNqb2HPd7cyY\"},hp:{},pcc:{}};google.y.first.push(function(){if(google.med){google.med('init');google.initHistory();google.med('history');}google.History&&google.History.initialize('/');google.hs&&google.hs.init&&google.hs.init()});if(google.j&&google.j.en&&google.j.xi){window.setTimeout(google.j.xi,0);}</script></div><script>(function(){var b,c,d,e;function g(a,f){a.removeEventListener?(a.removeEventListener(\"load\",f,!1),a.removeEventListener(\"error\",f,!1)):(a.detachEvent(\"onload\",f),a.detachEvent(\"onerror\",f))}function h(a){e=(new Date).getTime();++c;a=a||window.event;a=a.target||a.srcElement;g(a,h)}var i=document.getElementsByTagName(\"img\");b=i.length;\nfor(var j=c=0,k;j<b;++j)k=i[j],k.complete||\"string\"!=typeof k.src||!k.src?++c:k.addEventListener?(k.addEventListener(\"load\",h,!1),k.addEventListener(\"error\",h,!1)):(k.attachEvent(\"onload\",h),k.attachEvent(\"onerror\",h));d=b-c;\nfunction l(){if(google.timers.load.t){google.timers.load.t.ol=(new Date).getTime();google.timers.load.t.iml=e;google.kCSI.imc=c;google.kCSI.imn=b;google.kCSI.imp=d;void 0!==google.stt&&(google.kCSI.stt=google.stt);google.csiReport&&google.csiReport()}}window.addEventListener?window.addEventListener(\"load\",l,!1):window.attachEvent&&window.attachEvent(\"onload\",l);google.timers.load.t.prt=e=(new Date).getTime();})();\n</script></body></html>", { date: 'Sun, 27 Jan 2013 06:37:16 GMT',
expires: '-1',
'cache-control': 'private, max-age=0',
'content-type': 'text/html; charset=ISO-8859-1',
'set-cookie':
[ 'PREF=ID=64acdb01bb6414bd:FF=0:TM=1359268636:LM=1359268636:S=Xbza0PQd_o2cNH2J; expires=Tue, 27-Jan-2015 06:37:16 GMT; path=/; domain=.google.com',
'NID=67=nrAXvKbIMvA3042X2mbM1yUOp_4-eu_KrIPl8vIsCX00UG2wFVulXJNXAE35p_PUT2H0z-A1GckcEFAY_qgIr0JrTsKBHsYDLWzNRosoLpBvvzdBrZfifXaGj_ddkZL9; expires=Mon, 29-Jul-2013 06:37:16 GMT; path=/; domain=.google.com; HttpOnly' ],
p3p: 'CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."',
server: 'gws',
'x-xss-protection': '1; mode=block',
'x-frame-options': 'SAMEORIGIN',
'transfer-encoding': 'chunked' });
However, using it will fail to match, and output the following:
AssertionError: Mocks not yet satisfied:
GET google.com://80:443/
You can recreate this problem in the tests. In the first test of test/test_intercept.js
change the nock line:
var scope = nock('www.google.com')
Note the dropping of the protocol, matching the code generated by the recorder. The tests will fail after this change though!
I will be submitting a pull request correcting this.
When you stub out a host, any legitimate requests to that host (regardless of the path matching the actual stub or not) cause errors because no matching interception exists.
A quick example:
nock("http://localhost").get("/some/stubbed/path").reply(200, message)
request.get "http://localhost/", (err, res, body) ->
# blah blah blah
This would throw the following error:
Error: Nock: No match for HTTP request GET / undefined
The problem is that the keys in the allInterceptors
array done by host and a match triggers the processRequest
function which errors out when no match exists.
I made a simple workaround here: 9330dd26e393ee52dec9c094099cc72e4915fb7c
Unfortunately it's not really complete and causes the tests to fail. A fix would be to check for a complete match before processing the request, but I can't find an easy way to do that. If I can get a better idea of what would be required, I would be happy to put together a pull request when I have some time.
I see that nock lets you record http responses, but it looks like the feature is more so that you can fill in the tests yourself. Is there any support for more VCR-like functionality for recording and playing back HTTP requests and responses?
var nock = require('nock')
, request = require('request')
, assert = require('assert')
;
describe('foo', function () {
it('requests some data and does some stuff', function (done) {
// load the recorded request from the filename
// or save it there if it doesn't exist
nock.vrc('vcr-filename', function () {
request.get('http://example.com', function (err, response, body) { assert(body == 'HURP DURP'); done(); });
});
});
});
It would eliminate the step of having to manually go in and fill out the mock http requests in each of your tests, and would make it much easier to drop in to an existing project.
See
$ node tests/att/get.js
<<<<<<-- cut here -->>>>>>
nock('nodejsbug.iriscouch.com')
.put('/v061_att_gea')
.reply(201, "{\"ok\":true}\n", { server: 'CouchDB/1.1.1 (Erlang OTP/R14B04)',
location: 'http://nodejsbug.iriscouch.com/v061_att_gea',
date: 'Thu, 01 Dec 2011 21:39:15 GMT',
'content-type': 'application/json',
'content-length': '12',
'cache-control': 'must-revalidate' });
<<<<<<-- cut here -->>>>>>
<<<<<<-- cut here -->>>>>>
nock('nodejsbug.iriscouch.com')
.put('/v061_att_gea/new/att, "\"Hello\""')
.reply(201, "{\"ok\":true,\"id\":\"new\",\"rev\":\"1-5142a2e74e1ec33e6e5b621418210283\"}\n", { server: 'CouchDB/1.1.1 (Erlang OTP/R14B04)',
location: 'http://nodejsbug.iriscouch.com/v061_att_gea/new/att',
etag: '"1-5142a2e74e1ec33e6e5b621418210283"',
date: 'Thu, 01 Dec 2011 21:39:16 GMT',
'content-type': 'text/plain;charset=utf-8',
'content-length': '66',
'cache-control': 'must-revalidate' });
<<<<<<-- cut here -->>>>>>
<<<<<<-- cut here -->>>>>>
nock('nodejsbug.iriscouch.com')
.put('/v061_att_gea/new/att?rev=1-5142a2e74e1ec33e6e5b621418210283, "\"Hello\"BM:\u0000\u0000\u0000\u0000\u0000\u0000\u00006\u0000\u0000\u0000(\u0000\u0000\u0000\u0001\u0000\u0000\u0000????\u0001\u0000\u0018\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0013\u000b\u0000\u0000\u0013\u000b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000Zm?\u0000"')
.reply(201, "{\"ok\":true,\"id\":\"new\",\"rev\":\"2-3b1f88c637fde74a486cf3ce5558b47e\"}\n", { server: 'CouchDB/1.1.1 (Erlang OTP/R14B04)',
location: 'http://nodejsbug.iriscouch.com/v061_att_gea/new/att',
etag: '"2-3b1f88c637fde74a486cf3ce5558b47e"',
date: 'Thu, 01 Dec 2011 21:39:16 GMT',
'content-type': 'text/plain;charset=utf-8',
'content-length': '66',
'cache-control': 'must-revalidate' });
<<<<<<-- cut here -->>>>>>
<<<<<<-- cut here -->>>>>>
nock('nodejsbug.iriscouch.com')
.get('/v061_att_gea/new/att?rev=2-3b1f88c637fde74a486cf3ce5558b47e, "\"Hello\"BM:\u0000\u0000\u0000\u0000\u0000\u0000\u00006\u0000\u0000\u0000(\u0000\u0000\u0000\u0001\u0000\u0000\u0000????\u0001\u0000\u0018\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0013\u000b\u0000\u0000\u0013\u000b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000Zm?\u0000"')
.reply(200, "BM:\u0000\u0000\u0000\u0000\u0000\u0000\u00006\u0000\u0000\u0000(\u0000\u0000\u0000\u0001\u0000\u0000\u0000ÿÿÿÿ\u0001\u0000\u0018\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0013\u000b\u0000\u0000\u0013\u000b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000Zm�\u0000", { server: 'CouchDB/1.1.1 (Erlang OTP/R14B04)',
etag: '"2-3b1f88c637fde74a486cf3ce5558b47e"',
date: 'Thu, 01 Dec 2011 21:39:17 GMT',
'content-type': 'image/bmp',
'content-md5': 'Ow9j2dR0Qm58Qi3z8p2w3A==',
'content-length': '58',
'cache-control': 'must-revalidate',
'accept-ranges': 'bytes' });
<<<<<<-- cut here -->>>>>>
# /Users/dscape/Desktop/dev/nano/tests/att/get.js
ok 1 (unnamed assert)
ok 2 should be equal
1..2
# tests 2
# pass 2
# ok
<<<<<<-- cut here -->>>>>>
nock('nodejsbug.iriscouch.com')
.delete('/v061_att_gea, "\"Hello\"BM:\u0000\u0000\u0000\u0000\u0000\u0000\u00006\u0000\u0000\u0000(\u0000\u0000\u0000\u0001\u0000\u0000\u0000????\u0001\u0000\u0018\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0013\u000b\u0000\u0000\u0013\u000b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000Zm?\u0000"')
.reply(200, "{\"ok\":true}\n", { server: 'CouchDB/1.1.1 (Erlang OTP/R14B04)',
date: 'Thu, 01 Dec 2011 21:39:17 GMT',
'content-type': 'application/json',
'content-length': '12',
'cache-control': 'must-revalidate' });
<<<<<<-- cut here -->>>>>>
Strange huh? Body is always appended and always appears even in get requests.
When I use nock in OSX (10.8.1 w/ macports), it does not work & i get this error message when using an https host :
{"code":"ENOTFOUND","errno":"ENOTFOUND","syscall":"getaddrinfo"}
Any idea?
nock = require 'nock'
request = require 'request'
scope = nock('https://google.com', { allowUnmocked: true }).get("/abc").reply(200, "Hey!")
request { uri: 'https://google.com/' }, (err, resp, body) ->
console.log resp.statusCode
Output:
Error: Nock: No match for HTTP request GET /
the code works if you use http instead of https!
As pointed out by @indexzero here:
All it takes is one smart-ass library author (or ancient library) to use http.createClient or instantiate http.ClientRequest directly. This circumvents nock.
Seems like nock
doesnt support copy
.
Hy everyone. I'm building a proxy to forward some requests to a set of services.
The code I wrote is pretty simple and works just fine.
var nock = require('nock');
var http = require('http');
var httpProxy = require('http-proxy');
var config = {
'devices': 'localhost:3000/devices',
'types': 'localhost:3001/types',
'locations': 'localhost:3002/locations'
}
var options = {
router: {
'localhost/devices': config.devices,
'localhost/types': config.types,
'localhost/locations': config.locations,
}
}
var server = httpProxy.createServer(options).listen(8000);
The problem comes while trying to test it. I wanted to mock the http requests to the proxies services using nock, but somehow I'm not able to catch the requests. This is the code.
var nock = require('nock');
var http = require('http');
var request = require('request');
describe('when requires a resource', function() {
var fixture = __dirname + '/fixtures/devices.json';
var scope = nock('http://localhost:3000').get('/devices').replyWithFile('201', fixture);
it('keeps status code', function(done) {
request('http://localhost:8000/devices', function(error, res, body) {
expect(res.statusCode).toEqual('201');
done();
});
});
});
As you can see I call the running proxy server, which in turn proxy the request to the correct service. The problem is that the proxiest request is executed, and so, I can't test it. Am I missing something?
It would be really helpful if https requests could be mocked too. Thanks for creating this amazing package.
It would be great if nock would be tested on travis-ci.org. It's free and supports node, and can be set up in 5 minutes.
Sometimes a request will give different answers according to if that happened before.
e.g.
PUT NUNO foo -> OK
PUT NUNO BAR -> CONFLICT
OR
GET DB bar -> 404
PUT DB bar -> 201
GET DB bar -> 200
It should be possible to express this is nock. For the first request answer foo, for the second answer bar.
Real life example of code I hate to deprecate here: apache/nano@bb3f563
By the way watching a movie about the doors. Damn I'm tired :)
e.g. this fails.
nock('http://wtfjs.org')
.post('/like-wtf', {
foo: 'bar',
bar: 'foo'
});
request({
uri: http://wtfjs.org/like-wtf,
body: {
bar: 'foo',
foo: 'bar'
}, function () {
})
I noticed that in my tests using nock, if one test failed to fulfill an expectation, subsequent tests that set up the same expectation would fail, because the requests were being hijacked by a lingering intercept from the previous test. I wrote a test that demonstrates:
tap.test("scopes are independent", function(t) {
var scope1 = nock('http://www.google.com')
.get('/')
.reply(200, "Hello World!");
var scope2 = nock('http://www.google.com')
.get('/')
.reply(200, "Hello World!");
var req = http.request({
host: "www.google.com"
, path: '/'
, port: 80
}, function(res) {
res.on('end', function() {
t.ok(scope1.isDone());
t.ok(scope2.isDone()); // fails
t.end();
});
});
req.end();
});
What's your preferred way to fix this?
One intercepted request could fulfill expectations from multiple scopes (in other words, the above test would pass without modification).
nock.restore()
could clear out whatever is hanging around to cause this. Test would change to something like this:
tap.test("scopes are independent", function(t) {
var scope1 = nock(/*...*/);
nock.restore();
var scope2 = nock(/*...*/);
var req = http.request({
//...
}, function(res) {
res.on('end', function() {
t.notOk(scope1.isDone());
t.ok(scope2.isDone());
t.end();
});
});
req.end();
});
Similar to the previous option, but give the duty to a new method rather than restore
.
All my nock tests look like this:
if(process.env.NOCK) {
nock....
}
I would propose to make this a feature of nock:
var nock = require('nock');
nock.only(process.env.NOCK);
Hey guys, I'm having trouble with matched requests. I'm seeing Error: Nock: No match for HTTP request GET /1.1/users/lookup.json?user_id=&screen_name=lefnire
, yet that exact URL is nocked in my code. It's weird because using .log(console.log)
I see the Error: Nock: No matches
, then at the end see AssertionError: Mocks not yet satisfied
with all the previous no-matches verbatim.
Here's my code (stripped everything not relevant), and here's my error.
I would like to use the verbatim output of curl, including all the headers, store that in a file and use it to mock a request. Right now it seems that this is not possible (I might be mistaken)
The reason for this is that I am doing a lot of API, Oauth2 work that requires certain content present in header fields, and the only way to correctly test this is to use the exact output from curl (everything else seems to be prone to error).
Http allows to simply give the string of a URL instead of providing host, hostname, etc. separately. It would be great if you could add support for this with nock.
tap.test("accept string as request target", function(t) {
var scope = nock('http://www.example.com')
.get('/')
.reply(200, "Hello World!");
var req = http.get('http://www.example.com', function(res) {
t.equal(res.statusCode, 200);
res.on('end', function() {
t.ok(dataCalled);
scope.done();
t.end();
});
res.on('data', function(data) {
dataCalled = true;
t.ok(data instanceof Buffer, "data should be buffer");
t.equal(data.toString(), "Hello World!", "response should match");
});
});
req.end();
});
request headers might be critical factor on the success (or failure) of http requests, and need to be matched
Sorry if that is not the best to ask this.
But i am trying to use nock to mock the Shopify´s API, then i have some like this to get all blogs from a shop:
class Blog
constructor: (key, pass, shop) ->
throw new Error 'Blog missing parameters' if not pass? or not key? or not shop?
@options =
host: "http://#{key}:#{pass}@#{shop}.myshopify.com"
port: 80
method: "GET"
path: '/admin/blogs.json'
all: (cb) ->
req = request @options, (res) ->
response = ""
res.setEncoding('utf8')
res.on 'data', (data) ->
response += data
res.on 'end', ->
error = new Error 'Request Error #{res.statusCode}' unless res.statusCode is 200
process.nextTick ->
cb(error, JSON.parse(response))
req.end()
And parts of my testing they are some like this:
describe 'Receive a list of all Blogs', ->
before ->
@fixture = loadFixture 'blog/blogs'
@api = nock "https://#{KEY}:#{PASSWORD}@#{STORE}.myshopify.com"
@blog = new Blog KEY, PASSWORD, STORE
it 'should be possible get a list of all blog like an Array', (done) ->
@api.get('/admin/blogs.json').reply(200, @fixture)
@blog.all (err, blogs) =>
@api.done()
blogs.should.be.an.instanceof Object
done()
Sorry but i dont know what is wrong in my code, because allways get the response from the real server. But i need that my calls they are intercepting by nock to response my @fixture arrays of blogs.
Again sorry for ask that here.
Are ports supported or should all mocks be on 80 by default?
I've noticed some issues on nock not intercepting on when you specify :port
Nock should override and remove that override as needed, depending if there are any pending mocks or not.
I'm using mikeal/request with nock, and running this sample code doesn't pass:
nock = require 'nock'
request = require 'request'
expect = require('chai').expect
describe 'hello', ->
it 'hello', (done) ->
n = nock('https://hello.dev')
.post('/world')
.reply(200, 'hello world')
m = request.post {url: 'https://hello.dev/world'}, (err, res, body) ->
console.log body
done()
expect(n.isDone()).to.equal(true)
However, when I use https or http, it passes. Can anyone else reproduce this, or is this just an issue on my end?
Also want to add that if I change the expect to equal false, it does pass and "hello world" is indeed printed so nock does seem to catch the request, but it's still flagged as not done.
EDIT: It seems that the isDone() is running before it finishes maybe, which is weird since http works so I'll have to look into this a little more.
I was working on the new jitsu tests (nock is fabulous for this btw), and I came across an interesting situation when trying to mock snapshot uploads here:
https://github.com/nodejitsu/jitsu/blob/flatiron-apps-tests/test/commands/apps-test.js#L99
What happens here is that jitsu tries to post a snapshot using content-type chunked, and for the life of me I can't figure out how to specify a request body in such a way that nock is cool with it.
You can see some of the errors I was getting here:
https://gist.github.com/39d0e24897c8d339722a
The easiest thing for me would be to tell nock to accept any request body, but if I can figure out how to make it handle a chunked body (copy-pasting the string-encoded .tgz didn't help) I'd be happy with that as well.
Any ideas?
It would be more efficient if instead of buffering the entire file contents in sync, nock would stream the file through response
.
Response could be truly pipeable. Currently it only emits one data
event.
I've been trying to do this:
claim_req = Nock("http://uri", allowUnmocked: true)
.post("/claim", {some_data: "something"})
.reply(200)
I expected it to be caught, but it didn't. So I did a little digging around.
The method called matchIndependentOfBody
actually tries to match with the body. This line: https://github.com/flatiron/nock/blob/master/lib/scope.js#L155 does this: 'POST http://uri/claim:80 "{\"some_data\":\"something\"}"' === 'POST http://uri/claim:80'
because this._key
is already set with the body. Therefore the request is not intercepted.
Now if I remove the body, matchIndependentOfBody
returns true, but later on, it doesn't match the interceptor
because in another method named match
(https://github.com/flatiron/nock/blob/master/lib/scope.js#L101) it tries to match again, but this time with the body (https://github.com/flatiron/nock/blob/master/lib/scope.js#L132)
With or without a body, it doesn't work. I've also tried what's in the protip section of the readme, but the same result happens.
Am I doing something wrong?
Simply require nock and all should work.
Nock could save tests on the first run to the file system. Then replay wouldn't be done cause it was nocked.
A way to invalidate bad results would be necessary, so max a user would do is
nock.rewind();
> [email protected] test /Users/dscape/Desktop/dev/nano
> ./node_modules/ensure/bin/tap.js tests/*/*.js
ok destroy.js ....................... 4/4
ok get.js ........................... 3/3
ok insert.js ........................ 4/4
ok pipe.js .......................... 2/2
ok update.js ........................ 4/4
ok changes.js ....................... 4/4
ok compact.js ....................... 4/4
ok create.js ........................ 3/3
ok destroy.js ....................... 3/3
ok get.js ........................... 5/5
ok list.js .......................... 3/3
ok replicate.js ..................... 4/4
ok bulk.js .......................... 5/5
ok destroy.js ....................... 5/5
not ok get.js ...................... 9/10
Command: "node" "get.js"
ok 1 No excs
ok 2 I got rev
ok 3 My id is foo
ok 4 My foo is bar
not ok 5 Nock is done
---
file: /Users/dscape/Desktop/dev/nano/nano.js
line: 165
column: 11
stack:
- getCaller (/Users/dscape/Desktop/dev/nano/node_modules/ensure/node_modules/tap/node_modules/tap-assert/assert.js:370:17)
- Function.assert (/Users/dscape/Desktop/dev/nano/node_modules/ensure/node_modules/tap/node_modules/tap-assert/assert.js:17:16)
- Test._testAssert [as ok] (/Users/dscape/Desktop/dev/nano/node_modules/ensure/node_modules/tap/node_modules/tap-test/test.js:86:16)
- /Users/dscape/Desktop/dev/nano/tests/doc/get.js:84:10
- Request._callback (/Users/dscape/Desktop/dev/nano/nano.js:165:11)
- Request.callback (/Users/dscape/Desktop/dev/nano/node_modules/request/main.js:108:22)
- Request.<anonymous> (/Users/dscape/Desktop/dev/nano/node_modules/request/main.js:468:18)
- Request.emit (events.js:67:17)
- EventEmitter.<anonymous> (/Users/dscape/Desktop/dev/nano/node_modules/request/main.js:429:16)
- EventEmitter.emit (events.js:64:17)
unique: 4
...
ok 6 Err, not here
ok 7 Got revs info
ok 8 Id is food
ok 9 Bar is in foo
ok 10 Nock is done
1..10
# tests 10
# pass 9
# fail 1
ok insert.js ...................... 10/10
not ok list.js .................... 11/14
Command: "node" "list.js"
ok 1 No err
ok 2 3 Rows
ok 3 Got rows
not ok 4 Nock is done
---
file: /Users/dscape/Desktop/dev/nano/nano.js
line: 165
column: 11
stack:
- getCaller (/Users/dscape/Desktop/dev/nano/node_modules/ensure/node_modules/tap/node_modules/tap-assert/assert.js:370:17)
- Function.assert (/Users/dscape/Desktop/dev/nano/node_modules/ensure/node_modules/tap/node_modules/tap-assert/assert.js:17:16)
- Test._testAssert [as ok] (/Users/dscape/Desktop/dev/nano/node_modules/ensure/node_modules/tap/node_modules/tap-test/test.js:86:16)
- /Users/dscape/Desktop/dev/nano/tests/doc/list.js:168:10
- Request._callback (/Users/dscape/Desktop/dev/nano/nano.js:165:11)
- Request.callback (/Users/dscape/Desktop/dev/nano/node_modules/request/main.js:108:22)
- Request.<anonymous> (/Users/dscape/Desktop/dev/nano/node_modules/request/main.js:468:18)
- Request.emit (events.js:67:17)
- EventEmitter.<anonymous> (/Users/dscape/Desktop/dev/nano/node_modules/request/main.js:429:16)
- EventEmitter.emit (events.js:64:17)
unique: 3
...
ok 5 Not Err
ok 6 One Row
ok 7 Out of 3
ok 8 I got Rows
not ok 9 Nock is done
---
file: /Users/dscape/Desktop/dev/nano/nano.js
line: 165
column: 11
stack:
- getCaller (/Users/dscape/Desktop/dev/nano/node_modules/ensure/node_modules/tap/node_modules/tap-assert/assert.js:370:17)
- Function.assert (/Users/dscape/Desktop/dev/nano/node_modules/ensure/node_modules/tap/node_modules/tap-assert/assert.js:17:16)
- Test._testAssert [as ok] (/Users/dscape/Desktop/dev/nano/node_modules/ensure/node_modules/tap/node_modules/tap-test/test.js:86:16)
- /Users/dscape/Desktop/dev/nano/tests/doc/list.js:193:10
- Request._callback (/Users/dscape/Desktop/dev/nano/nano.js:165:11)
- Request.callback (/Users/dscape/Desktop/dev/nano/node_modules/request/main.js:108:22)
- Request.<anonymous> (/Users/dscape/Desktop/dev/nano/node_modules/request/main.js:468:18)
- Request.emit (events.js:67:17)
- EventEmitter.<anonymous> (/Users/dscape/Desktop/dev/nano/node_modules/request/main.js:429:16)
- EventEmitter.emit (events.js:64:17)
unique: 8
...
ok 10 No errs
ok 11 Two rows returned
ok 12 Out of 3
ok 13 That means we got rows
not ok 14 Nock is done
---
file: /Users/dscape/Desktop/dev/nano/nano.js
line: 165
column: 11
stack:
- getCaller (/Users/dscape/Desktop/dev/nano/node_modules/ensure/node_modules/tap/node_modules/tap-assert/assert.js:370:17)
- Function.assert (/Users/dscape/Desktop/dev/nano/node_modules/ensure/node_modules/tap/node_modules/tap-assert/assert.js:17:16)
- Test._testAssert [as ok] (/Users/dscape/Desktop/dev/nano/node_modules/ensure/node_modules/tap/node_modules/tap-test/test.js:86:16)
- /Users/dscape/Desktop/dev/nano/tests/doc/list.js:214:10
- Request._callback (/Users/dscape/Desktop/dev/nano/nano.js:165:11)
- Request.callback (/Users/dscape/Desktop/dev/nano/node_modules/request/main.js:108:22)
- Request.<anonymous> (/Users/dscape/Desktop/dev/nano/node_modules/request/main.js:468:18)
- Request.emit (events.js:67:17)
- EventEmitter.<anonymous> (/Users/dscape/Desktop/dev/nano/node_modules/request/main.js:429:16)
- EventEmitter.emit (events.js:64:17)
unique: 13
...
1..14
# tests 14
# pass 11
# fail 3
ok update.js ........................ 5/5
ok create.js ........................ 0/0
ok delete.js ........................ 0/0
ok cfg.js ......................... 19/19
ok error.js ......................... 8/8
ok nano.js .......................... 2/2
ok compact.js ....................... 3/3
ok multi-document-fetch.js .......... 5/5
ok query.js ......................... 6/6
total ........................... 157/161
not ok
npm.log
info it worked if it ends with ok
verbose cli [ 'node', '/usr/local/bin/npm', 'test' ]
info using [email protected]
info using [email protected]
verbose config file /Users/dscape/.npmrc
verbose config file /usr/local/etc/npmrc
verbose config file /usr/local/lib/node_modules/npm/npmrc
silly testEngine { name: 'nano',
silly testEngine description: 'minimalistic couchdb driver for node.js',
silly testEngine homepage: 'http://github.com/dscape/nano',
silly testEngine repository: { type: 'git', url: 'git://github.com/dscape/nano.git' },
silly testEngine version: '1.1.0',
silly testEngine author:
silly testEngine { name: 'Nuno Job',
silly testEngine email: '[email protected]',
silly testEngine url: 'http://nunojob.com' },
silly testEngine contributors:
silly testEngine [ { name: 'Thiago Arrais',
silly testEngine email: '[email protected]',
silly testEngine url: 'http://thiagoarrais.com' },
silly testEngine { name: 'Derek Perez',
silly testEngine email: '[email protected]',
silly testEngine url: 'http://blog.derekperez.com' },
silly testEngine { name: 'Patrick Heneise', url: 'http://patrickheneise.me' },
silly testEngine { name: 'Artur Konarski', url: 'http://tarantoga.com' },
silly testEngine { name: 'Pedro Teixeira',
silly testEngine email: '[email protected]',
silly testEngine url: 'http://metaduck.com' } ],
silly testEngine keywords:
silly testEngine [ 'couchdb',
silly testEngine 'data',
silly testEngine 'request',
silly testEngine 'json',
silly testEngine 'nosql',
silly testEngine 'micro',
silly testEngine 'nano',
silly testEngine 'database' ],
silly testEngine dependencies: { request: '2.9.3', underscore: '1.2.3' },
silly testEngine devDependencies:
silly testEngine { async: '0.1.15',
silly testEngine ensure: '0.4.6',
silly testEngine nock: '*',
silly testEngine 'tap-runner': '0.0.7',
silly testEngine 'tap-producer': '0.0.1',
silly testEngine tap: '0.1.3',
silly testEngine inherits: '1.0.0',
silly testEngine yamlish: '0.0.2',
silly testEngine slide: '1.1.3' },
silly testEngine scripts: { test: './node_modules/ensure/bin/tap.js tests/*/*.js' },
silly testEngine main: './nano.js',
silly testEngine engines: { node: '>=0.3.6' },
silly testEngine _npmUser: { name: 'dscape', email: '[email protected]' },
silly testEngine _id: '[email protected]',
silly testEngine _engineSupported: true,
silly testEngine _npmVersion: '1.0.106',
silly testEngine _nodeVersion: 'v0.6.1',
silly testEngine _defaultsLoaded: true }
verbose caching /Users/dscape/Desktop/dev/nano/package.json
verbose loadDefaults [email protected]
verbose run-script [ 'pretest', 'test', 'posttest' ]
info pretest [email protected]
info test [email protected]
verbose unsafe-perm in lifecycle true
silly exec sh "-c" "./node_modules/ensure/bin/tap.js tests/*/*.js"
silly spawning [ 'sh',
silly spawning [ '-c', './node_modules/ensure/bin/tap.js tests/*/*.js' ],
silly spawning '/Users/dscape/Desktop/dev/nano' ]
info [email protected] Failed to exec test script
ERR! [email protected] test: `./node_modules/ensure/bin/tap.js tests/*/*.js`
ERR! `sh "-c" "./node_modules/ensure/bin/tap.js tests/*/*.js"` failed with 4
ERR!
ERR! Failed at the [email protected] test script.
ERR! This is most likely a problem with the nano package,
ERR! not with npm itself.
ERR! Tell the author that this fails on your system:
ERR! ./node_modules/ensure/bin/tap.js tests/*/*.js
ERR! You can get their info via:
ERR! npm owner ls nano
ERR! There is likely additional logging output above.
ERR!
ERR! System Darwin 11.2.0
ERR! command "node" "/usr/local/bin/npm" "test"
ERR! cwd /Users/dscape/Desktop/dev/nano
ERR! node -v v0.6.1
ERR! npm -v 1.0.106
ERR! code ELIFECYCLE
verbose exit [ 1, true ]
I'm having some trouble with query strings. I wish to intercept a path like '/path/load' which can accept multiple parameters, like '?b=123&a=456'. The trouble is that "a" "b" could be in any order (since it'd still be a valid URL). Is there some way I could do parameter matching like the POST request using an object map instead of constructing this string?
nock('https://httpbin.org', { allowUnmocked: true }).get("/abc").reply(200, "Hey!");
var options = {
method: 'post',
uri: 'https://httpbin.org/post',
json: { some: 'data' }
};
request(options, function(err, resp, body) {
console.log(resp.statusCode, body);
});
The console.log
is never run. The same code works if you do any of the following:
allowUnmocked: true
Hi,
I'm trying to use the #filteringRequestBody method but it doesn't work. Actually I tried both the function and regexp version without results. Here my code.
request = nock('http://mqtt.lelylan.com')
.filteringRequestBody(/"nonce":"[^"]*/g, '"nonce":"30e7f667"')
.matchHeader('X-Physical-Signature', signature)
.put('/physicals/1', {'properties': {}, 'nonce': '30e7f667'})
.reply(202);
I also tried with the function method as my regexp skills are a disaster, but nothing.
request = nock('http://mqtt.lelylan.com')
.filteringRequestBody(function(path) {
return {'properties': {}, 'nonce': '30e7f667'};
})
.matchHeader('X-Physical-Signature', signature)
.put('/physicals/1', {'properties': {}, 'nonce': '30e7f667'})
.reply(202);
What I want to do is to replace the nonce
param (from JSON) to a fixed one. Unluckily it doesn't change and i get back the following message where I can see how the nonce is not updated.
Error: Nock: No match for HTTP request PUT /physicals/1
{"properties":{},"nonce":"011dcb6d-7305-4e13-a2b4-e3e363a5a41b"}
Am I missing something?
Thanks a lot
Is this possible?
Right now recordings generate code that, among other things, include a builder pattern with a function that is named after the HTTP verb. The problem is that the scope may not support that verb.
E.g.:
nock('http://ciserversdk.table.core.windows.net:80')
.filteringRequestBody(function (path) { return '';})
.merge('/tableservice12(PartitionKey=%27part1%27,RowKey=%27row1%27)', '')
.reply(204, "", { 'cache-control': 'no-cache',
'content-length': '0',
date: 'Thu, 21 Feb 2013 00:30:56 GMT' });
A better solution would be to generate (at least for the ones that are not trivial / supported) the recordings with a generic http verb processing mechanism.
Example:
.request('merge', 'tableservice12' foobar)
.reply(foobar)
I'm having an issue mocking a request using Request (https://github.com/mikeal/request/) where I'm making multiple chained requests
scope = nock('http://localhost:3000)
.get('/')
.replyWithFile(__dirname + '../support/example.html')
.get('/')
.replyWithFile(__dirname + '../support/example2.html')
request url ->
request url ->
The second request won't get processed for some reason I have yet to figure out. Changing replyWithFile
with reply
and using readFile
produces the correct results, so perhaps it has something to do with streaming? I will try to reproduce it separately.
Some headers can be set multiple times on a request, I believe node supports this by allowing header values to be arrays.
Unless there's an undocumented feature I'm missing matchHeader won't work because of this snippet:
var checkHeaders = function(header) {
return options.getHeader(header.name) === header.value;
};
I think changing it to the following should be sufficient:
var checkHeaders = function(header) {
var value = options.getHeader(header.name)
if (Array.isArray(value)) {
return value.indexOf(header.value) != -1
} else {
return value == header.value
}
};
Thoughts?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.