UNPKG

60.8 kBMarkdownView Raw
1# Nock
2
3[![npm](https://img.shields.io/npm/v/nock.svg)][npmjs]
4[![Build Status](https://travis-ci.org/nock/nock.svg)][build]
5![Coverage Status](http://img.shields.io/badge/coverage-100%25-brightgreen.svg)
6[![Backers on Open Collective](https://opencollective.com/nock/backers/badge.svg)](#backers)
7[![Sponsors on Open Collective](https://opencollective.com/nock/sponsors/badge.svg)](#sponsors)
8
9[npmjs]: https://www.npmjs.com/package/nock
10[build]: https://travis-ci.org/nock/nock
11
12> **Notice**
13>
14> We have introduced experimental support for fetch. Please share your feedback with us. You can install it by:
15>
16> ```
17> npm install --save-dev nock@beta
18> ```
19
20HTTP server mocking and expectations library for Node.js
21
22Nock can be used to test modules that perform HTTP requests in isolation.
23
24For instance, if a module performs HTTP requests to a CouchDB server or makes HTTP requests to the Amazon API, you can test that module in isolation.
25
26**Table of Contents**
27
28<!-- toc -->
29
30- [How does it work?](#how-does-it-work)
31- [Install](#install)
32 - [Node version support](#node-version-support)
33- [Usage](#usage)
34 - [READ THIS! - About interceptors](#read-this---about-interceptors)
35 - [Specifying hostname](#specifying-hostname)
36 - [Specifying path](#specifying-path)
37 - [Specifying request body](#specifying-request-body)
38 - [Specifying request query string](#specifying-request-query-string)
39 - [Specifying replies](#specifying-replies)
40 - [Access original request and headers](#access-original-request-and-headers)
41 - [Replying with errors](#replying-with-errors)
42 - [Specifying headers](#specifying-headers)
43 - [Header field names are case-insensitive](#header-field-names-are-case-insensitive)
44 - [Specifying Request Headers](#specifying-request-headers)
45 - [Specifying Reply Headers](#specifying-reply-headers)
46 - [Default Reply Headers](#default-reply-headers)
47 - [Including Content-Length Header Automatically](#including-content-length-header-automatically)
48 - [Including Date Header Automatically](#including-date-header-automatically)
49 - [HTTP Verbs](#http-verbs)
50 - [Support for HTTP and HTTPS](#support-for-http-and-https)
51 - [Non-standard ports](#non-standard-ports)
52 - [Repeat response n times](#repeat-response-n-times)
53 - [Delay the response](#delay-the-response)
54 - [Delay the connection](#delay-the-connection)
55 - [Technical Details](#technical-details)
56 - [Delay the response body](#delay-the-response-body)
57 - [Technical Details](#technical-details-1)
58 - [Chaining](#chaining)
59 - [Scope filtering](#scope-filtering)
60 - [Conditional scope filtering](#conditional-scope-filtering)
61 - [Path filtering](#path-filtering)
62 - [Request Body filtering](#request-body-filtering)
63 - [Request Headers Matching](#request-headers-matching)
64 - [Optional Requests](#optional-requests)
65 - [Allow **unmocked** requests on a mocked hostname](#allow-unmocked-requests-on-a-mocked-hostname)
66- [Expectations](#expectations)
67 - [.isDone()](#isdone)
68 - [.cleanAll()](#cleanall)
69 - [.abortPendingRequests()](#abortpendingrequests)
70 - [.persist()](#persist)
71 - [.pendingMocks()](#pendingmocks)
72 - [.activeMocks()](#activemocks)
73 - [.isActive()](#isactive)
74 - [.clone()](#clone)
75- [Restoring](#restoring)
76- [Activating](#activating)
77- [Turning Nock Off (experimental!)](#turning-nock-off-experimental)
78- [Enable/Disable real HTTP requests](#enabledisable-real-http-requests)
79 - [Disabling requests](#disabling-requests)
80 - [Enabling requests](#enabling-requests)
81 - [Resetting NetConnect](#resetting-netconnect)
82- [Recording](#recording)
83 - [`dont_print` option](#dont_print-option)
84 - [`output_objects` option](#output_objects-option)
85 - [`enable_reqheaders_recording` option](#enable_reqheaders_recording-option)
86 - [`logging` option](#logging-option)
87 - [`use_separator` option](#use_separator-option)
88 - [.removeInterceptor()](#removeinterceptor)
89- [Events](#events)
90 - [Global no match event](#global-no-match-event)
91- [Nock Back](#nock-back)
92 - [Setup](#setup)
93 - [Options](#options)
94 - [Usage](#usage-1)
95 - [Options](#options-1)
96 - [Example](#example)
97 - [Modes](#modes)
98 - [Verifying recorded fixtures](#verifying-recorded-fixtures)
99 - [Example](#example-1)
100- [Common issues](#common-issues)
101 - [Axios](#axios)
102 - [Memory issues with Jest](#memory-issues-with-jest)
103- [Debugging](#debugging)
104- [Contributing](#contributing)
105- [Contributors](#contributors)
106- [Sponsors](#sponsors)
107- [License](#license)
108
109<!-- tocstop -->
110
111## How does it work?
112
113Nock works by overriding Node's `http.request` function. Also, it overrides `http.ClientRequest` too to cover for modules that use it directly.
114
115## Install
116
117```sh
118$ npm install --save-dev nock
119```
120
121### Node version support
122
123The latest version of nock supports all currently maintained Node versions, see [Node Release Schedule](https://github.com/nodejs/Release#release-schedule)
124
125Here is a list of past nock versions with respective node version support
126
127| node | nock |
128| ---- | ---------- |
129| 0.10 | up to 8.x |
130| 0.11 | up to 8.x |
131| 0.12 | up to 8.x |
132| 4 | up to 9.x |
133| 5 | up to 8.x |
134| 6 | up to 10.x |
135| 7 | up to 9.x |
136| 8 | up to 11.x |
137| 9 | up to 9.x |
138
139## Usage
140
141On your test, you can setup your mocking object like this:
142
143```js
144const nock = require('nock')
145
146const scope = nock('https://api.github.com')
147 .get('/repos/atom/atom/license')
148 .reply(200, {
149 license: {
150 key: 'mit',
151 name: 'MIT License',
152 spdx_id: 'MIT',
153 url: 'https://api.github.com/licenses/mit',
154 node_id: 'MDc6TGljZW5zZTEz',
155 },
156 })
157```
158
159This setup says that we will intercept every HTTP call to `https://api.github.com`.
160
161It will intercept an HTTPS GET request to `/repos/atom/atom/license`, reply with
162a status 200, and the body will contain a (partial) response in JSON.
163
164### READ THIS! - About interceptors
165
166When you setup an interceptor for a URL and that interceptor is used, it is removed from the interceptor list.
167This means that you can intercept 2 or more calls to the same URL and return different things on each of them.
168It also means that you must setup one interceptor for each request you are going to have, otherwise nock will throw an error because that URL was not present in the interceptor list.
169If you don’t want interceptors to be removed as they are used, you can use the [.persist()](#persist) method.
170
171### Specifying hostname
172
173The request hostname can be a string, URL, or a RegExp.
174
175```js
176const scope = nock('http://www.example.com')
177 .get('/resource')
178 .reply(200, 'domain matched')
179```
180
181```js
182const scope = nock(new URL('http://www.example.com'))
183 .get('/resource')
184 .reply(200, 'domain matched')
185```
186
187```js
188const scope = nock(/example\.com/)
189 .get('/resource')
190 .reply(200, 'domain regex matched')
191```
192
193> Note: You can choose to include or not the protocol in the hostname matching.
194
195### Specifying path
196
197The request path can be a string, a RegExp or a filter function and you can use any [HTTP verb](#http-verbs).
198
199Using a string:
200
201```js
202const scope = nock('http://www.example.com')
203 .get('/resource')
204 .reply(200, 'path matched')
205```
206
207Using a regular expression:
208
209```js
210const scope = nock('http://www.example.com')
211 .get(/source$/)
212 .reply(200, 'path using regex matched')
213```
214
215Using a function:
216
217```js
218const scope = nock('http://www.example.com')
219 .get(uri => uri.includes('cats'))
220 .reply(200, 'path using function matched')
221```
222
223### Specifying request body
224
225You can specify the request body to be matched as the second argument to the `get`, `post`, `put` or `delete` specifications. There are five types of second argument allowed:
226
227**String**: nock will exact match the stringified request body with the provided string
228
229```js
230nock('http://www.example.com')
231 .post('/login', 'username=pgte&password=123456')
232 .reply(200, { id: '123ABC' })
233```
234
235**Buffer**: nock will exact match the stringified request body with the provided buffer
236
237```js
238nock('http://www.example.com')
239 .post('/login', Buffer.from([0xff, 0x11]))
240 .reply(200, { id: '123ABC' })
241```
242
243**RegExp**: nock will test the stringified request body against the provided RegExp
244
245```js
246nock('http://www.example.com')
247 .post('/login', /username=\w+/gi)
248 .reply(200, { id: '123ABC' })
249```
250
251**JSON object**: nock will exact match the request body with the provided object. In order to increase flexibility, nock also supports RegExp as an attribute value for the keys:
252
253```js
254nock('http://www.example.com')
255 .post('/login', { username: 'pgte', password: /.+/i })
256 .reply(200, { id: '123ABC' })
257```
258
259**Function**: nock will evaluate the function providing the request body object as first argument. Return true if it should be considered a match:
260
261```js
262nock('http://www.example.com')
263 .post('/login', body => body.username && body.password)
264 .reply(200, { id: '123ABC' })
265```
266
267In case you need to perform a partial matching on a complex, nested request body you should have a look at libraries like [lodash.matches](https://lodash.com/docs/#matches). Indeed, partial matching can be achieved as:
268
269```js
270nock('http://www.example.com')
271 .post('/user', _.matches({ address: { country: 'US' } }))
272 .reply(200, { id: '123ABC' })
273```
274
275### Specifying request query string
276
277Nock understands query strings. Search parameters can be included as part of the path:
278
279```js
280nock('http://example.com').get('/users?foo=bar').reply(200)
281```
282
283Instead of placing the entire URL, you can specify the query part as an object:
284
285```js
286nock('http://example.com')
287 .get('/users')
288 .query({ name: 'pedro', surname: 'teixeira' })
289 .reply(200, { results: [{ id: 'pgte' }] })
290```
291
292Nock supports array-style/object-style query parameters. The encoding format matches with request module.
293
294```js
295nock('http://example.com')
296 .get('/users')
297 .query({
298 names: ['alice', 'bob'],
299 tags: {
300 alice: ['admin', 'tester'],
301 bob: ['tester'],
302 },
303 })
304 .reply(200, { results: [{ id: 'pgte' }] })
305```
306
307A `URLSearchParams` instance can be provided.
308
309```js
310const params = new URLSearchParams({ foo: 'bar' })
311
312nock('http://example.com').get('/').query(params).reply(200)
313```
314
315Nock supports passing a function to query. The function determines if the actual query matches or not.
316
317```js
318nock('http://example.com')
319 .get('/users')
320 .query(actualQueryObject => {
321 // do some compare with the actual Query Object
322 // return true for matched
323 // return false for not matched
324 return true
325 })
326 .reply(200, { results: [{ id: 'pgte' }] })
327```
328
329To mock the entire url regardless of the passed query string:
330
331```js
332nock('http://example.com')
333 .get('/users')
334 .query(true)
335 .reply(200, { results: [{ id: 'pgte' }] })
336```
337
338A query string that is already [URL encoded](https://en.wikipedia.org/wiki/Percent-encoding) can be
339matched by passing the `encodedQueryParams` flag in the options when creating the Scope.
340
341```js
342nock('http://example.com', { encodedQueryParams: true })
343 .get('/users')
344 .query('foo%5Bbar%5D%3Dhello%20world%21')
345 .reply(200, { results: [{ id: 'pgte' }] })
346```
347
348### Specifying replies
349
350You can specify the return status code for a path on the first argument of reply like this:
351
352```js
353const scope = nock('http://myapp.iriscouch.com').get('/users/1').reply(404)
354```
355
356You can also specify the reply body as a string:
357
358```js
359const scope = nock('http://www.google.com')
360 .get('/')
361 .reply(200, 'Hello from Google!')
362```
363
364or as a JSON-encoded object:
365
366```js
367const scope = nock('http://myapp.iriscouch.com').get('/').reply(200, {
368 username: 'pgte',
369 email: 'pedro.teixeira@gmail.com',
370 _id: '4324243fsd',
371})
372```
373
374or even as a file:
375
376```js
377const scope = nock('http://myapp.iriscouch.com')
378 .get('/')
379 .replyWithFile(200, __dirname + '/replies/user.json', {
380 'Content-Type': 'application/json',
381 })
382```
383
384Instead of an object or a buffer you can also pass in a callback to be evaluated for the value of the response body:
385
386```js
387const scope = nock('http://www.google.com')
388 .post('/echo')
389 .reply(201, (uri, requestBody) => requestBody)
390```
391
392In Nock 11.x it was possible to invoke `.reply()` with a status code and a
393function that returns an array containing a status code and body. (The status
394code from the array would take precedence over the one passed directly to
395reply.) This is no longer allowed. In Nock 12 and later, either call `.reply()` with a
396status code and a function that returns the body, or call it with a single
397argument: a function that returns an array containing both the status code and
398body.
399
400An asynchronous function that gets an error-first callback as its last argument also works:
401
402```js
403const scope = nock('http://www.google.com')
404 .post('/echo')
405 .reply(201, (uri, requestBody, cb) => {
406 fs.readFile('cat-poems.txt', cb) // Error-first callback
407 })
408```
409
410In Nock 11 and later, if an error is passed to the callback, Nock will rethrow it as a programmer error.
411In Nock 10 and earlier, the error was sent in the response body, with a 500 HTTP response status code.
412
413You can also return the status code and body using just one function:
414
415```js
416const scope = nock('http://www.google.com')
417 .post('/echo')
418 .reply((uri, requestBody) => {
419 return [
420 201,
421 'THIS IS THE REPLY BODY',
422 { header: 'value' }, // optional headers
423 ]
424 })
425```
426
427or, use an error-first callback that also gets the status code:
428
429```js
430const scope = nock('http://www.google.com')
431 .post('/echo')
432 .reply((uri, requestBody, cb) => {
433 setTimeout(() => cb(null, [201, 'THIS IS THE REPLY BODY']), 1000)
434 })
435```
436
437A Stream works too:
438
439```js
440const scope = nock('http://www.google.com')
441 .get('/cat-poems')
442 .reply(200, (uri, requestBody) => {
443 return fs.createReadStream('cat-poems.txt')
444 })
445```
446
447#### Access original request and headers
448
449If you're using the reply callback style, you can access the original client request using `this.req` like this:
450
451```js
452const scope = nock('http://www.google.com')
453 .get('/cat-poems')
454 .reply(function (uri, requestBody) {
455 console.log('path:', this.req.path)
456 console.log('headers:', this.req.headers)
457 // ...
458 })
459```
460
461> Note: Remember to use normal `function` in that case, as arrow functions are using enclosing scope for `this` binding.
462
463#### Replying with errors
464
465You can reply with an error like this:
466
467```js
468nock('http://www.google.com')
469 .get('/cat-poems')
470 .replyWithError('something awful happened')
471```
472
473JSON error responses are allowed too:
474
475```js
476nock('http://www.google.com').get('/cat-poems').replyWithError({
477 message: 'something awful happened',
478 code: 'AWFUL_ERROR',
479})
480```
481
482> Note: This will emit an `error` event on the `request` object, not the reply.
483
484### Specifying headers
485
486#### Header field names are case-insensitive
487
488Per [HTTP/1.1 4.2 Message Headers](http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2) specification, all message headers are case insensitive and thus internally Nock uses lower-case for all field names even if some other combination of cases was specified either in mocking specification or in mocked requests themselves.
489
490#### Specifying Request Headers
491
492You can specify the request headers like this:
493
494```js
495const scope = nock('http://www.example.com', {
496 reqheaders: {
497 authorization: 'Basic Auth',
498 },
499})
500 .get('/')
501 .reply(200)
502```
503
504Or you can use a regular expression or function to check the header values. The
505function will be passed the header value.
506
507```js
508const scope = nock('http://www.example.com', {
509 reqheaders: {
510 'X-My-Headers': headerValue => headerValue.includes('cats'),
511 'X-My-Awesome-Header': /Awesome/i,
512 },
513})
514 .get('/')
515 .reply(200)
516```
517
518If `reqheaders` is not specified or if `host` is not part of it, Nock will automatically add `host` value to request header.
519
520If no request headers are specified for mocking then Nock will automatically skip matching of request headers. Since the `host` header is a special case which may get automatically inserted by Nock, its matching is skipped unless it was _also_ specified in the request being mocked.
521
522You can also have Nock fail the request if certain headers are present:
523
524```js
525const scope = nock('http://www.example.com', {
526 badheaders: ['cookie', 'x-forwarded-for'],
527})
528 .get('/')
529 .reply(200)
530```
531
532When invoked with this option, Nock will not match the request if any of the `badheaders` are present.
533
534Basic authentication can be specified as follows:
535
536```js
537const scope = nock('http://www.example.com')
538 .get('/')
539 .basicAuth({ user: 'john', pass: 'doe' })
540 .reply(200)
541```
542
543#### Specifying Reply Headers
544
545You can specify the reply headers like this:
546
547```js
548const scope = nock('https://api.github.com')
549 .get('/repos/atom/atom/license')
550 .reply(200, { license: 'MIT' }, { 'X-RateLimit-Remaining': 4999 })
551```
552
553Or you can use a function to generate the headers values. The function will be
554passed the request, response, and response body (if available). The body will
555be either a buffer, a stream, or undefined.
556
557```js
558const scope = nock('http://www.headdy.com')
559 .get('/')
560 .reply(200, 'Hello World!', {
561 'Content-Length': (req, res, body) => body.length,
562 ETag: () => `${Date.now()}`,
563 })
564```
565
566#### Default Reply Headers
567
568You can also specify default reply headers for all responses like this:
569
570```js
571const scope = nock('http://www.headdy.com')
572 .defaultReplyHeaders({
573 'X-Powered-By': 'Rails',
574 'Content-Type': 'application/json',
575 })
576 .get('/')
577 .reply(200, 'The default headers should come too')
578```
579
580Or you can use a function to generate the default headers values:
581
582```js
583const scope = nock('http://www.headdy.com')
584 .defaultReplyHeaders({
585 'Content-Length': (req, res, body) => body.length,
586 })
587 .get('/')
588 .reply(200, 'The default headers should come too')
589```
590
591#### Including Content-Length Header Automatically
592
593When using `interceptor.reply()` to set a response body manually, you can have the
594`Content-Length` header calculated automatically.
595
596```js
597const scope = nock('http://www.headdy.com')
598 .replyContentLength()
599 .get('/')
600 .reply(200, { hello: 'world' })
601```
602
603**NOTE:** this does not work with streams or other advanced means of specifying
604the reply body.
605
606#### Including Date Header Automatically
607
608You can automatically append a `Date` header to your mock reply:
609
610```js
611const scope = nock('http://www.headdy.com')
612 .replyDate()
613 .get('/')
614 .reply(200, { hello: 'world' })
615```
616
617Or provide your own `Date` object:
618
619```js
620const scope = nock('http://www.headdy.com')
621 .replyDate(new Date(2015, 0, 1))
622 .get('/')
623 .reply(200, { hello: 'world' })
624```
625
626### HTTP Verbs
627
628Nock supports any HTTP verb, and it has convenience methods for the GET, POST, PUT, HEAD, DELETE, PATCH, OPTIONS and MERGE HTTP verbs.
629
630You can intercept any HTTP verb using `.intercept(path, verb [, requestBody [, options]])`:
631
632```js
633const scope = nock('http://my.domain.com')
634 .intercept('/path', 'PATCH')
635 .reply(304)
636```
637
638### Support for HTTP and HTTPS
639
640By default nock assumes HTTP. If you need to use HTTPS you can specify the `https://` prefix like this:
641
642```js
643const scope = nock('https://secure.my.server.com')
644// ...
645```
646
647### Non-standard ports
648
649You are able to specify a non-standard port like this:
650
651```js
652const scope = nock('http://my.server.com:8081')
653```
654
655### Repeat response n times
656
657You are able to specify the number of times to repeat the same response.
658
659**NOTE:** When request times is more than the number you specified, you will get an error before cleaning this interceptor.
660
661```js
662nock('http://zombo.com').get('/').times(4).reply(200, 'Ok')
663
664http.get('http://zombo.com/') // respond body "Ok"
665http.get('http://zombo.com/') // respond body "Ok"
666http.get('http://zombo.com/') // respond body "Ok"
667http.get('http://zombo.com/') // respond body "Ok"
668
669// This code will get an error with message:
670// Nock: No match for request
671http.get('http://zombo.com/')
672
673// clean your interceptor
674nock.cleanAll()
675
676http.get('http://zombo.com/') // real respond with zombo.com result
677```
678
679Sugar syntax
680
681```js
682nock('http://zombo.com').get('/').once().reply(200, 'Ok')
683nock('http://zombo.com').get('/').twice().reply(200, 'Ok')
684nock('http://zombo.com').get('/').thrice().reply(200, 'Ok')
685```
686
687To repeat this response for as long as nock is active, use [.persist()](#persist).
688
689### Delay the response
690
691Nock can simulate response latency to allow you to test timeouts, race conditions, an other timing related scenarios.
692You are able to specify the number of milliseconds that your reply should be delayed.
693
694```js
695nock('http://my.server.com')
696 .get('/')
697 .delay(2000) // 2 seconds delay will be applied to the response header.
698 .reply(200, '<html></html>')
699```
700
701`delay(1000)` is an alias for `delayConnection(1000).delayBody(0)`
702`delay({ head: 1000, body: 2000 })` is an alias for `delayConnection(1000).delayBody(2000)`
703Both of which are covered in detail below.
704
705#### Delay the connection
706
707You are able to specify the number of milliseconds that your connection should be idle before it starts to receive the response.
708
709To simulate a socket timeout, provide a larger value than the timeout setting on the request.
710
711```js
712nock('http://my.server.com')
713 .get('/')
714 .delayConnection(2000) // 2 seconds
715 .reply(200, '<html></html>')
716
717req = http.request('http://my.server.com', { timeout: 1000 })
718```
719
720Nock emits timeout events almost immediately by comparing the requested connection delay to the timeout parameter passed to `http.request()` or `http.ClientRequest#setTimeout()`.
721This allows you to test timeouts without using fake timers or slowing down your tests.
722If the client chooses to _not_ take an action (e.g. abort the request), the request and response will continue on as normal, after real clock time has passed.
723
724##### Technical Details
725
726Following the `'finish'` event being emitted by `ClientRequest`, Nock will wait for the next event loop iteration before checking if the request has been aborted.
727At this point, any connection delay value is compared against any request timeout setting and a [`'timeout'`](https://nodejs.org/api/http.html#http_event_timeout) is emitted when appropriate from the socket and the request objects.
728A Node timeout timer is then registered with any connection delay value to delay real time before checking again if the request has been aborted and the [`'response'`](http://nodejs.org/api/http.html#http_event_response) is emitted by the request.
729
730A similar method, `.socketDelay()` was removed in version 13. It was thought that having two methods so subtlety similar was confusing.
731The discussion can be found at https://github.com/nock/nock/pull/1974.
732
733#### Delay the response body
734
735You are able to specify the number of milliseconds that the response body should be delayed.
736This is the time between the headers being received and the body starting to be received.
737
738```js
739nock('http://my.server.com')
740 .get('/')
741 .delayBody(2000) // 2 seconds
742 .reply(200, '<html></html>')
743```
744
745##### Technical Details
746
747Following the [`'response'`](http://nodejs.org/api/http.html#http_event_response) being emitted by `ClientRequest`,
748Nock will register a timeout timer with the body delay value to delay real time before the [IncomingMessage](http://nodejs.org/api/http.html#http_http_incomingmessage) emits its first `'data'` or the `'end'` event.
749
750### Chaining
751
752You can chain behaviour like this:
753
754```js
755const scope = nock('http://myapp.iriscouch.com')
756 .get('/users/1')
757 .reply(404)
758 .post('/users', {
759 username: 'pgte',
760 email: 'pedro.teixeira@gmail.com',
761 })
762 .reply(201, {
763 ok: true,
764 id: '123ABC',
765 rev: '946B7D1C',
766 })
767 .get('/users/123ABC')
768 .reply(200, {
769 _id: '123ABC',
770 _rev: '946B7D1C',
771 username: 'pgte',
772 email: 'pedro.teixeira@gmail.com',
773 })
774```
775
776### Scope filtering
777
778You can filter the scope (protocol, domain or port) of nock through a function. The filtering function is accepted at the `filteringScope` field of the `options` argument.
779
780This can be useful if you have a node module that randomly changes subdomains to which it sends requests, e.g., the Dropbox node module behaves like this.
781
782```js
783const scope = nock('https://api.dropbox.com', {
784 filteringScope: scope => /^https:\/\/api[0-9]*.dropbox.com/.test(scope),
785})
786 .get('/1/metadata/auto/Photos?include_deleted=false&list=true')
787 .reply(200)
788```
789
790### Conditional scope filtering
791
792You can also choose to filter out a scope based on your system environment (or any external factor). The filtering function is accepted at the `conditionally` field of the `options` argument.
793
794This can be useful if you only want certain scopes to apply depending on how your tests are executed.
795
796```js
797const scope = nock('https://api.myservice.com', {
798 conditionally: () => true,
799})
800```
801
802### Path filtering
803
804You can also filter the URLs based on a function.
805
806This can be useful, for instance, if you have random or time-dependent data in your URL.
807
808You can use a regexp for replacement, just like String.prototype.replace:
809
810```js
811const scope = nock('http://api.myservice.com')
812 .filteringPath(/password=[^&]*/g, 'password=XXX')
813 .get('/users/1?password=XXX')
814 .reply(200, 'user')
815```
816
817Or you can use a function:
818
819```js
820const scope = nock('http://api.myservice.com')
821 .filteringPath(path => '/ABC')
822 .get('/ABC')
823 .reply(200, 'user')
824```
825
826Note that `scope.filteringPath` is not cumulative: it should only be used once per scope.
827
828### Request Body filtering
829
830You can also filter the request body based on a function.
831
832This can be useful, for instance, if you have random or time-dependent data in your request body.
833
834You can use a regexp for replacement, just like String.prototype.replace:
835
836```js
837const scope = nock('http://api.myservice.com')
838 .filteringRequestBody(/password=[^&]*/g, 'password=XXX')
839 .post('/users/1', 'data=ABC&password=XXX')
840 .reply(201, 'OK')
841```
842
843Or you can use a function to transform the body:
844
845```js
846const scope = nock('http://api.myservice.com')
847 .filteringRequestBody(body => 'ABC')
848 .post('/', 'ABC')
849 .reply(201, 'OK')
850```
851
852If you don't want to match the request body you should omit the `body` argument from the method function:
853
854```js
855const scope = nock('http://api.myservice.com')
856 .post('/some_uri') // no body argument
857 .reply(200, 'OK')
858```
859
860### Request Headers Matching
861
862If you need to match requests only if certain request headers match, you can.
863
864```js
865const scope = nock('http://api.myservice.com')
866 // Interceptors created after here will only match when the header `accept` equals `application/json`.
867 .matchHeader('accept', 'application/json')
868 .get('/')
869 .reply(200, {
870 data: 'hello world',
871 })
872 .get('/')
873 // Only this interceptor will match the header value `x-my-action` with `MyFirstAction`
874 .matchHeader('x-my-action', 'MyFirstAction')
875 .reply(200, {
876 data: 'FirstActionResponse',
877 })
878 .get('/')
879 // Only this interceptor will match the header value `x-my-action` with `MySecondAction`
880 .matchHeader('x-my-action', 'MySecondAction')
881 .reply(200, {
882 data: 'SecondActionResponse',
883 })
884```
885
886You can also use a regexp for the header body.
887
888```js
889const scope = nock('http://api.myservice.com')
890 .matchHeader('User-Agent', /Mozilla\/.*/)
891 .get('/')
892 .reply(200, {
893 data: 'hello world',
894 })
895```
896
897You can also use a function for the header body.
898
899```js
900const scope = nock('http://api.myservice.com')
901 .matchHeader('content-length', val => val >= 1000)
902 .get('/')
903 .reply(200, {
904 data: 'hello world',
905 })
906```
907
908### Optional Requests
909
910By default every mocked request is expected to be made exactly once, and until it is it'll appear in `scope.pendingMocks()`, and `scope.isDone()` will return false (see [expectations](#expectations)). In many cases this is fine, but in some (especially cross-test setup code) it's useful to be able to mock a request that may or may not happen. You can do this with `optionally()`. Optional requests are consumed just like normal ones once matched, but they do not appear in `pendingMocks()`, and `isDone()` will return true for scopes with only optional requests pending.
911
912```js
913const example = nock('http://example.com')
914example.pendingMocks() // []
915example.get('/pathA').reply(200)
916example.pendingMocks() // ["GET http://example.com:80/path"]
917
918// ...After a request to example.com/pathA:
919example.pendingMocks() // []
920
921example.get('/pathB').optionally().reply(200)
922example.pendingMocks() // []
923
924// You can also pass a boolean argument to `optionally()`. This
925// is useful if you want to conditionally make a mocked request
926// optional.
927const getMock = optional =>
928 example.get('/pathC').optionally(optional).reply(200)
929
930getMock(true)
931example.pendingMocks() // []
932getMock(false)
933example.pendingMocks() // ["GET http://example.com:80/pathC"]
934```
935
936### Allow **unmocked** requests on a mocked hostname
937
938If you need some request on the same host name to be mocked and some others to **really** go through the HTTP stack, you can use the `allowUnmocked` option like this:
939
940```js
941const scope = nock('http://my.existing.service.com', { allowUnmocked: true })
942 .get('/my/url')
943 .reply(200, 'OK!')
944
945// GET /my/url => goes through nock
946// GET /other/url => actually makes request to the server
947```
948
949> Note: When applying `{allowUnmocked: true}`, if the request is made to the real server, no interceptor is removed.
950
951## Expectations
952
953Every time an HTTP request is performed for a scope that is mocked, Nock expects to find a handler for it. If it doesn't, it will throw an error.
954
955Calls to nock() return a scope which you can assert by calling `scope.done()`. This will assert that all specified calls on that scope were performed.
956
957Example:
958
959```js
960const scope = nock('http://google.com')
961 .get('/')
962 .reply(200, 'Hello from Google!')
963
964// do some stuff
965
966setTimeout(() => {
967 // Will throw an assertion error if meanwhile a "GET http://google.com" was
968 // not performed.
969 scope.done()
970}, 5000)
971```
972
973### .isDone()
974
975You can call `isDone()` on a single expectation to determine if the expectation was met:
976
977```js
978const scope = nock('http://google.com').get('/').reply(200)
979
980scope.isDone() // will return false
981```
982
983It is also available in the global scope, which will determine if all expectations have been met:
984
985```js
986nock.isDone()
987```
988
989### .cleanAll()
990
991You can cleanup all the prepared mocks (could be useful to cleanup some state after a failed test) like this:
992
993```js
994nock.cleanAll()
995```
996
997### .abortPendingRequests()
998
999You can abort all current pending request like this:
1000
1001```js
1002nock.abortPendingRequests()
1003```
1004
1005### .persist()
1006
1007You can make all the interceptors for a scope persist by calling `.persist()` on it:
1008
1009```js
1010const scope = nock('http://example.com')
1011 .persist()
1012 .get('/')
1013 .reply(200, 'Persisting all the way')
1014```
1015
1016Note that while a persisted scope will always intercept the requests, it is considered "done" after the first interception.
1017
1018If you want to stop persisting an individual persisted mock you can call `persist(false)`:
1019
1020```js
1021const scope = nock('http://example.com').persist().get('/').reply(200, 'ok')
1022
1023// Do some tests ...
1024
1025scope.persist(false)
1026```
1027
1028You can also use `nock.cleanAll()` which removes all mocks, including persistent mocks.
1029
1030To specify an exact number of times that nock should repeat the response, use [.times()](#repeat-response-n-times).
1031
1032### .pendingMocks()
1033
1034If a scope is not done, you can inspect the scope to infer which ones are still pending using the `scope.pendingMocks()` function:
1035
1036```js
1037if (!scope.isDone()) {
1038 console.error('pending mocks: %j', scope.pendingMocks())
1039}
1040```
1041
1042It is also available in the global scope:
1043
1044```js
1045console.error('pending mocks: %j', nock.pendingMocks())
1046```
1047
1048### .activeMocks()
1049
1050You can see every mock that is currently active (i.e. might potentially reply to requests) in a scope using `scope.activeMocks()`. A mock is active if it is pending, optional but not yet completed, or persisted. Mocks that have intercepted their requests and are no longer doing anything are the only mocks which won't appear here.
1051
1052You probably don't need to use this - it mainly exists as a mechanism to recreate the previous (now-changed) behavior of `pendingMocks()`.
1053
1054```js
1055console.error('active mocks: %j', scope.activeMocks())
1056```
1057
1058It is also available in the global scope:
1059
1060```js
1061console.error('active mocks: %j', nock.activeMocks())
1062```
1063
1064### .isActive()
1065
1066Your tests may sometimes want to deactivate the nock interceptor.
1067Once deactivated, nock needs to be re-activated to work.
1068You can check if nock interceptor is active or not by using `nock.isActive()`.
1069Sample:
1070
1071```js
1072if (!nock.isActive()) {
1073 nock.activate()
1074}
1075```
1076
1077### .clone()
1078
1079You can clone a scope by calling `.clone()` on it:
1080
1081```js
1082const scope = nock('http://example.test')
1083
1084const getScope = scope.get('/').reply(200)
1085const postScope = scope.clone().post('/').reply(200)
1086```
1087
1088## Restoring
1089
1090You can restore the HTTP interceptor to the normal unmocked behaviour by calling:
1091
1092```js
1093nock.restore()
1094```
1095
1096**note 1**: restore does not clear the interceptor list. Use [nock.cleanAll()](#cleanall) if you expect the interceptor list to be empty.
1097
1098**note 2**: restore will also remove the http interceptor itself. You need to run [nock.activate()](#activating) to re-activate the http interceptor. Without re-activation, nock will not intercept any calls.
1099
1100## Activating
1101
1102Only for cases where nock has been deactivated using [nock.restore()](#restoring), you can reactivate the HTTP interceptor to start intercepting HTTP calls using:
1103
1104```js
1105nock.activate()
1106```
1107
1108**note**: To check if nock HTTP interceptor is active or inactive, use [nock.isActive()](#isactive).
1109
1110## Turning Nock Off (experimental!)
1111
1112You can bypass Nock completely by setting the `NOCK_OFF` environment variable to `"true"`.
1113
1114This way you can have your tests hit the real servers just by switching on this environment variable.
1115
1116```shell script
1117$ NOCK_OFF=true node my_test.js
1118```
1119
1120## Enable/Disable real HTTP requests
1121
1122By default, any requests made to a host that is not mocked will be executed normally. If you want to block these requests, nock allows you to do so.
1123
1124### Disabling requests
1125
1126For disabling real http requests.
1127
1128```js
1129nock.disableNetConnect()
1130```
1131
1132So, if you try to request any host not 'nocked', it will throw a `NetConnectNotAllowedError`.
1133
1134```js
1135nock.disableNetConnect()
1136const req = http.get('http://google.com/')
1137req.on('error', err => {
1138 console.log(err)
1139})
1140// The returned `http.ClientRequest` will emit an error event (or throw if you're not listening for it)
1141// This code will log a NetConnectNotAllowedError with message:
1142// Nock: Disallowed net connect for "google.com:80"
1143```
1144
1145### Enabling requests
1146
1147For enabling any real HTTP requests (the default behavior):
1148
1149```js
1150nock.enableNetConnect()
1151```
1152
1153You could allow real HTTP requests for certain host names by providing a string or a regular expression for the hostname, or a function that accepts the hostname and returns true or false:
1154
1155```js
1156// Using a string
1157nock.enableNetConnect('amazon.com')
1158
1159// Or a RegExp
1160nock.enableNetConnect(/(amazon|github)\.com/)
1161
1162// Or a Function
1163nock.enableNetConnect(
1164 host => host.includes('amazon.com') || host.includes('github.com'),
1165)
1166
1167http.get('http://www.amazon.com/')
1168http.get('http://github.com/')
1169
1170http.get('http://google.com/')
1171// This will throw NetConnectNotAllowedError with message:
1172// Nock: Disallowed net connect for "google.com:80"
1173```
1174
1175A common use case when testing local endpoints would be to disable all but localhost, then add in additional nocks for external requests:
1176
1177```js
1178nock.disableNetConnect()
1179// Allow localhost connections so we can test local routes and mock servers.
1180nock.enableNetConnect('127.0.0.1')
1181```
1182
1183### Resetting NetConnect
1184
1185When you're done with the test, you probably want to set everything back to normal:
1186
1187```js
1188nock.cleanAll()
1189nock.enableNetConnect()
1190```
1191
1192## Recording
1193
1194This is a cool feature:
1195
1196Guessing what the HTTP calls are is a mess, especially if you are introducing nock on your already-coded tests.
1197
1198For these cases where you want to mock an existing live system you can record and playback the HTTP calls like this:
1199
1200```js
1201nock.recorder.rec()
1202// Some HTTP calls happen and the nock code necessary to mock
1203// those calls will be outputted to console
1204```
1205
1206Recording relies on intercepting real requests and responses and then persisting them for later use.
1207
1208In order to stop recording you should call `nock.restore()` and recording will stop.
1209
1210**ATTENTION!:** when recording is enabled, nock does no validation, nor will any mocks be enabled. Please be sure to turn off recording before attempting to use any mocks in your tests.
1211
1212### `dont_print` option
1213
1214If you just want to capture the generated code into a var as an array you can use:
1215
1216```js
1217nock.recorder.rec({
1218 dont_print: true,
1219})
1220// ... some HTTP calls
1221const nockCalls = nock.recorder.play()
1222```
1223
1224The `nockCalls` var will contain an array of strings representing the generated code you need.
1225
1226Copy and paste that code into your tests, customize at will, and you're done! You can call `nock.recorder.clear()` to remove already recorded calls from the array that `nock.recorder.play()` returns.
1227
1228(Remember that you should do this one test at a time).
1229
1230### `output_objects` option
1231
1232In case you want to generate the code yourself or use the test data in some other way, you can pass the `output_objects` option to `rec`:
1233
1234```js
1235nock.recorder.rec({
1236 output_objects: true,
1237})
1238// ... some HTTP calls
1239const nockCallObjects = nock.recorder.play()
1240```
1241
1242The returned call objects have the following properties:
1243
1244- `scope` - the scope of the call including the protocol and non-standard ports (e.g. `'https://github.com:12345'`)
1245- `method` - the HTTP verb of the call (e.g. `'GET'`)
1246- `path` - the path of the call (e.g. `'/pgte/nock'`)
1247- `body` - the body of the call, if any
1248- `status` - the HTTP status of the reply (e.g. `200`)
1249- `response` - the body of the reply which can be a JSON, string, hex string representing binary buffers or an array of such hex strings (when handling `content-encoded` in reply header)
1250- `rawHeaders` - the headers of the reply which are formatted as a flat array containing header name and header value pairs (e.g. `['accept', 'application/json', 'set-cookie', 'my-cookie=value']`)
1251- `reqheader` - the headers of the request
1252
1253If you save this as a JSON file, you can load them directly through `nock.load(path)`. Then you can post-process them before using them in the tests. For example, to add request body filtering (shown here fixing timestamps to match the ones captured during recording):
1254
1255```js
1256nocks = nock.load(pathToJson)
1257nocks.forEach(function (nock) {
1258 nock.filteringRequestBody = (body, aRecordedBody) => {
1259 if (typeof body !== 'string' || typeof aRecordedBody !== 'string') {
1260 return body
1261 }
1262
1263 const recordedBodyResult = /timestamp:([0-9]+)/.exec(aRecordedBody)
1264 if (recordedBodyResult) {
1265 const recordedTimestamp = recordedBodyResult[1]
1266 return body.replace(
1267 /(timestamp):([0-9]+)/g,
1268 function (match, key, value) {
1269 return key + ':' + recordedTimestamp
1270 },
1271 )
1272 } else {
1273 return body
1274 }
1275 }
1276})
1277```
1278
1279Alternatively, if you need to pre-process the captured nock definitions before
1280using them (e.g. to add scope filtering) then you can use `nock.loadDefs(path)`
1281and `nock.define(nockDefs)`. Shown here is scope filtering for Dropbox node
1282module which constantly changes the subdomain to which it sends the requests:
1283
1284```js
1285// Pre-process the nock definitions as scope filtering has to be defined before the nocks are defined (due to its very hacky nature).
1286const nockDefs = nock.loadDefs(pathToJson)
1287nockDefs.forEach(def => {
1288 // Do something with the definition object e.g. scope filtering.
1289 def.options = {
1290 ...def.options,
1291 filteringScope: scope => /^https:\/\/api[0-9]*.dropbox.com/.test(scope),
1292 }
1293})
1294
1295// Load the nocks from pre-processed definitions.
1296const nocks = nock.define(nockDefs)
1297```
1298
1299### `enable_reqheaders_recording` option
1300
1301Recording request headers by default is deemed more trouble than it's worth as some of them depend on the timestamp or other values that may change after the tests have been recorded thus leading to complex postprocessing of recorded tests. Thus by default the request headers are not recorded.
1302
1303The genuine use cases for recording request headers (e.g. checking authorization) can be handled manually or by using `enable_reqheaders_recording` in `recorder.rec()` options.
1304
1305```js
1306nock.recorder.rec({
1307 dont_print: true,
1308 output_objects: true,
1309 enable_reqheaders_recording: true,
1310})
1311```
1312
1313Note that even when request headers recording is enabled Nock will never record `user-agent` headers. `user-agent` values change with the version of Node and underlying operating system and are thus useless for matching as all that they can indicate is that the user agent isn't the one that was used to record the tests.
1314
1315### `logging` option
1316
1317Nock will print using `console.log` by default (assuming that `dont_print` is `false`). If a different function is passed into `logging`, nock will send the log string (or object, when using `output_objects`) to that function. Here's a basic example.
1318
1319```js
1320const appendLogToFile = content => {
1321 fs.appendFile('record.txt', content)
1322}
1323nock.recorder.rec({
1324 logging: appendLogToFile,
1325})
1326```
1327
1328### `use_separator` option
1329
1330By default, nock will wrap its output with the separator string `<<<<<<-- cut here -->>>>>>` before and after anything it prints, whether to the console or a custom log function given with the `logging` option.
1331
1332To disable this, set `use_separator` to false.
1333
1334```js
1335nock.recorder.rec({
1336 use_separator: false,
1337})
1338```
1339
1340### .removeInterceptor()
1341
1342This allows removing a specific interceptor. This can be either an interceptor instance or options for a url. It's useful when there's a list of common interceptors shared between tests, where an individual test requires one of the shared interceptors to behave differently.
1343
1344Examples:
1345
1346```js
1347nock.removeInterceptor({
1348 hostname: 'localhost',
1349 path: '/mockedResource',
1350})
1351```
1352
1353```js
1354nock.removeInterceptor({
1355 hostname: 'localhost',
1356 path: '/login',
1357 method: 'POST',
1358 proto: 'https',
1359})
1360```
1361
1362```js
1363const interceptor = nock('http://example.org').get('somePath')
1364nock.removeInterceptor(interceptor)
1365```
1366
1367**Note** `.reply(...)` method returns Scope, not Interceptor, and so it is not a valid argument for `nock.removeInterceptor`. So if your method chain ends with `.reply` to be used with `nock.removeInterceptor` the chain need to be break in between:
1368
1369```js
1370// this will NOT work
1371const interceptor = nock('http://example.org').get('somePath').reply(200, 'OK')
1372nock.removeInterceptor(interceptor)
1373// this is how it should be
1374const interceptor = nock('http://example.org').get('somePath')
1375interceptor.reply(200, 'OK')
1376nock.removeInterceptor(interceptor)
1377```
1378
1379## Events
1380
1381A scope emits the following events:
1382
1383- `emit('request', function(req, interceptor, body))`
1384- `emit('replied', function(req, interceptor))`
1385
1386### Global no match event
1387
1388You can also listen for no match events like this:
1389
1390```js
1391nock.emitter.on('no match', req => {})
1392```
1393
1394## Nock Back
1395
1396Fixture recording support and playback.
1397
1398### Setup
1399
1400You must specify a fixture directory before using, for example:
1401
1402In your test helper
1403
1404```js
1405const nockBack = require('nock').back
1406
1407nockBack.fixtures = '/path/to/fixtures/'
1408nockBack.setMode('record')
1409```
1410
1411#### Options
1412
1413- `nockBack.fixtures` : path to fixture directory
1414- `nockBack.setMode()` : the mode to use
1415
1416### Usage
1417
1418By default if the fixture doesn't exist, a `nockBack` will create a new fixture and save the recorded output
1419for you. The next time you run the test, if the fixture exists, it will be loaded in.
1420
1421The `this` context of the callback function will have a property `scopes` to access all of the loaded
1422nock scopes.
1423
1424```js
1425const nockBack = require('nock').back
1426const request = require('request')
1427nockBack.setMode('record')
1428
1429nockBack.fixtures = __dirname + '/nockFixtures' //this only needs to be set once in your test helper
1430
1431// recording of the fixture
1432nockBack('zomboFixture.json', nockDone => {
1433 request.get('http://zombo.com', (err, res, body) => {
1434 nockDone()
1435
1436 // usage of the created fixture
1437 nockBack('zomboFixture.json', function (nockDone) {
1438 http.get('http://zombo.com/').end() // respond body "Ok"
1439
1440 this.assertScopesFinished() //throws an exception if all nocks in fixture were not satisfied
1441 http.get('http://zombo.com/').end() // throws exception because someFixture.json only had one call
1442
1443 nockDone() //never gets here
1444 })
1445 })
1446})
1447```
1448
1449If your tests are using promises then use `nockBack` like this:
1450
1451```js
1452return nockBack('promisedFixture.json').then(({ nockDone, context }) => {
1453 // do your tests returning a promise and chain it with
1454 // `.then(nockDone)`
1455})
1456```
1457
1458Or, with async/await:
1459
1460```js
1461const { nockDone, context } = await nockBack('promisedFixture.json')
1462// your test code
1463nockDone()
1464```
1465
1466#### Options
1467
1468As an optional second parameter you can pass the following options
1469
1470- `before`: a preprocessing function, gets called before nock.define
1471- `after`: a postprocessing function, gets called after nock.define
1472- `afterRecord`: a postprocessing function, gets called after recording. Is passed the array of scopes recorded and should return the intact array, a modified version of the array, or if custom formatting is desired, a stringified version of the array to save to the fixture
1473- `recorder`: custom options to pass to the recorder
1474
1475##### Example
1476
1477```js
1478function prepareScope(scope) {
1479 scope.filteringRequestBody = (body, aRecordedBody) => {
1480 if (typeof body !== 'string' || typeof aRecordedBody !== 'string') {
1481 return body
1482 }
1483
1484 const recordedBodyResult = /timestamp:([0-9]+)/.exec(aRecordedBody)
1485 if (recordedBodyResult) {
1486 const recordedTimestamp = recordedBodyResult[1]
1487 return body.replace(
1488 /(timestamp):([0-9]+)/g,
1489 (match, key, value) => `${key}:${recordedTimestamp}`,
1490 )
1491 } else {
1492 return body
1493 }
1494 }
1495}
1496
1497nockBack('exampleFixture.json', { before: prepareScope }, nockDone => {
1498 request.get('http://example.com', function (err, res, body) {
1499 // do your tests
1500 nockDone()
1501 })
1502})
1503```
1504
1505### Modes
1506
1507To set the mode call `nockBack.setMode(mode)` or run the tests with the `NOCK_BACK_MODE` environment variable set before loading nock. If the mode needs to be changed programmatically, the following is valid: `nockBack.setMode(nockBack.currentMode)`
1508
1509- wild: all requests go out to the internet, don't replay anything, doesn't record anything
1510
1511- dryrun: The default, use recorded nocks, allow http calls, doesn't record anything, useful for writing new tests
1512
1513- record: use recorded nocks, record new nocks
1514
1515- update: remove recorded nocks, record nocks
1516
1517- lockdown: use recorded nocks, disables all http calls even when not nocked, doesn't record
1518
1519### Verifying recorded fixtures
1520
1521Although you can certainly open the recorded JSON fixtures to manually verify requests recorded by nockBack - it's sometimes useful to put those expectations in your tests.
1522
1523The `context.query` function can be used to return all of the interceptors that were recored in a given fixture.
1524
1525By itself, this functions as a negative expectation - you can verify that certain calls do NOT happen in the fixture. Since `assertScopesFinished` can verify there are no _extra_ calls in a fixture - pairing the two methods allows you to verify the exact set of HTTP interactions recorded in the fixture. This is especially useful when re-recording for instance, a service that synchronizes via several HTTP calls to an external API.
1526
1527**NB**: The list of fixtures is only available when reading. It will only be populated for nocks that are played back from fixtures.
1528
1529#### Example
1530
1531```js
1532it('#synchronize - synchronize with the external API', async localState => {
1533 const { nockDone, context } = await back('http-interaction.json')
1534
1535 const syncronizer = new Synchronizer(localState)
1536
1537 sycnronizer.syncronize()
1538
1539 nockDone()
1540
1541 context.assertScopesFinished()
1542
1543 expect(context.query()).toEqual(
1544 expect.arrayContaining([
1545 expect.objectContaining({
1546 method: 'POST',
1547 path: '/create/thing',
1548 }),
1549 expect.objectContaining({
1550 method: 'POST',
1551 path: 'create/thing',
1552 }),
1553 ]),
1554 )
1555})
1556```
1557
1558## Common issues
1559
1560**"No match for response" when using got with error responses**
1561
1562[Got][] automatically retries failed requests twice. That means if you have a
1563test which mocks a 4xx or 5xx response, got will immediately reissue it. At
1564that point, the mock will have been consumed and the second request will error
1565out with **Nock: No match for request**.
1566
1567The same is true for `.replyWithError()`.
1568
1569Adding `{ retry: 0 }` to the `got` invocations will disable retrying, e.g.:
1570
1571```js
1572await got('http://example.test/', { retry: 0 })
1573```
1574
1575If you need to do this in all your tests, you can create a module
1576`got_client.js` which exports a custom got instance:
1577
1578```js
1579const got = require('got')
1580
1581module.exports = got.extend({ retry: 0 })
1582```
1583
1584This is how it's handled in Nock itself (see [#1523][]).
1585
1586[got]: https://github.com/sindresorhus/got
1587[#1523]: https://github.com/nock/nock/issues/1523
1588
1589### Axios
1590
1591To use Nock with [Axios][], you may need to configure Axios to use the Node
1592adapter as in the example below:
1593
1594```js
1595import axios from 'axios'
1596import nock from 'nock'
1597import test from 'ava' // You can use any test framework.
1598
1599// If you are using jsdom, axios will default to using the XHR adapter which
1600// can't be intercepted by nock. So, configure axios to use the node adapter.
1601//
1602// References:
1603// https://github.com/axios/axios/pull/5277
1604
1605axios.defaults.adapter = 'http'
1606
1607test('can fetch test response', async t => {
1608 // Set up the mock request.
1609 const scope = nock('http://localhost')
1610 .get('/test')
1611 .reply(200, 'test response')
1612
1613 // Make the request. Note that the hostname must match exactly what is passed
1614 // to `nock()`. Alternatively you can set `axios.defaults.host = 'http://localhost'`
1615 // and run `axios.get('/test')`.
1616 await axios.get('http://localhost/test')
1617
1618 // Assert that the expected request was made.
1619 scope.done()
1620})
1621```
1622
1623For Nock + Axios + Jest to work, you'll have to also adapt your jest.config.js, like so:
1624
1625```js
1626const config = {
1627 moduleNameMapper: {
1628 // Force CommonJS build for http adapter to be available.
1629 // via https://github.com/axios/axios/issues/5101#issuecomment-1276572468
1630 '^axios$': require.resolve('axios'),
1631 },
1632}
1633```
1634
1635[axios]: https://github.com/axios/axios
1636
1637### Memory issues with Jest
1638
1639Memory issues can be avoided by calling [`nock.restore()`](#restoring) after each test suite.
1640One of the core principles of [Jest](https://jestjs.io/) is that it runs tests in isolation.
1641It does this by manipulating the modules cache of Node in a way that conflicts with how Nock monkey patches the builtin `http` and `https` modules.
1642[Related issue with more details](https://github.com/nock/nock/issues/1817).
1643
1644## Debugging
1645
1646Nock uses [`debug`](https://github.com/visionmedia/debug), so just run with environmental variable `DEBUG` set to `nock.*`.
1647
1648```console
1649user@local$ DEBUG=nock.* node my_test.js
1650```
1651
1652Each step in the matching process is logged this way and can be useful when determining why a request was not intercepted by Nock.
1653
1654For example the following shows that matching failed because the request had an extra search parameter.
1655
1656```js
1657nock('http://example.com').get('/').query({ foo: 'bar' }).reply()
1658
1659await got('http://example.com/?foo=bar&baz=foz')
1660```
1661
1662```console
1663user@local$ DEBUG=nock.scope:example.com node my_test.js
1664...
1665nock.scope:example.com Interceptor queries: {"foo":"bar"} +1ms
1666nock.scope:example.com Request queries: {"foo":"bar","baz":"foz"} +0ms
1667nock.scope:example.com query matching failed +0ms
1668```
1669
1670## Contributing
1671
1672Thanks for wanting to contribute! Take a look at our [Contributing Guide](CONTRIBUTING.md) for notes on our commit message conventions and how to run tests.
1673
1674Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md).
1675By participating in this project you agree to abide by its terms.
1676
1677## Contributors
1678
1679Thanks goes to these wonderful people ([emoji key](https://github.com/all-contributors/all-contributors#emoji-key)):
1680
1681<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
1682<!-- prettier-ignore-start -->
1683<!-- markdownlint-disable -->
1684<table>
1685 <tbody>
1686 <tr>
1687 <td align="center" valign="top" width="14.28%"><a href="http://pgte.me"><img src="https://avatars1.githubusercontent.com/u/47910?v=4?s=100" width="100px;" alt="Pedro Teixeira"/><br /><sub><b>Pedro Teixeira</b></sub></a><br /><a href="https://github.com/nock/nock/commits?author=pgte" title="Code">πŸ’»</a> <a href="#maintenance-pgte" title="Maintenance">🚧</a></td>
1688 <td align="center" valign="top" width="14.28%"><a href="https://github.com/n30n0v"><img src="https://avatars3.githubusercontent.com/u/10771967?v=4?s=100" width="100px;" alt="n30n0v"/><br /><sub><b>n30n0v</b></sub></a><br /><a href="https://github.com/nock/nock/commits?author=n30n0v" title="Code">πŸ’»</a></td>
1689 <td align="center" valign="top" width="14.28%"><a href="https://burntfen.com"><img src="https://avatars3.githubusercontent.com/u/910753?v=4?s=100" width="100px;" alt="Richard Littauer"/><br /><sub><b>Richard Littauer</b></sub></a><br /><a href="#maintenance-RichardLitt" title="Maintenance">🚧</a> <a href="https://github.com/nock/nock/commits?author=RichardLitt" title="Code">πŸ’»</a> <a href="#blog-RichardLitt" title="Blogposts">πŸ“</a></td>
1690 <td align="center" valign="top" width="14.28%"><a href="http://ianwsperber.com"><img src="https://avatars1.githubusercontent.com/u/3731165?v=4?s=100" width="100px;" alt="Ian Walker-Sperber"/><br /><sub><b>Ian Walker-Sperber</b></sub></a><br /><a href="https://github.com/nock/nock/commits?author=ianwsperber" title="Code">πŸ’»</a></td>
1691 <td align="center" valign="top" width="14.28%"><a href="http://ilovacha.com"><img src="https://avatars2.githubusercontent.com/u/1505203?v=4?s=100" width="100px;" alt="Ivan Erceg"/><br /><sub><b>Ivan Erceg</b></sub></a><br /><a href="https://github.com/nock/nock/commits?author=ierceg" title="Code">πŸ’»</a> <a href="#maintenance-ierceg" title="Maintenance">🚧</a></td>
1692 <td align="center" valign="top" width="14.28%"><a href="https://twitter.com/paulmelnikow"><img src="https://avatars2.githubusercontent.com/u/1487036?v=4?s=100" width="100px;" alt="Paul Melnikow"/><br /><sub><b>Paul Melnikow</b></sub></a><br /><a href="https://github.com/nock/nock/commits?author=paulmelnikow" title="Code">πŸ’»</a> <a href="#maintenance-paulmelnikow" title="Maintenance">🚧</a></td>
1693 <td align="center" valign="top" width="14.28%"><a href="https://twitter.com/gr2m"><img src="https://avatars3.githubusercontent.com/u/39992?v=4?s=100" width="100px;" alt="Gregor Martynus"/><br /><sub><b>Gregor Martynus</b></sub></a><br /><a href="https://github.com/nock/nock/commits?author=gr2m" title="Code">πŸ’»</a> <a href="#maintenance-gr2m" title="Maintenance">🚧</a> <a href="#business-gr2m" title="Business development">πŸ’Ό</a> <a href="#financial-gr2m" title="Financial">πŸ’΅</a> <a href="#blog-gr2m" title="Blogposts">πŸ“</a></td>
1694 </tr>
1695 <tr>
1696 <td align="center" valign="top" width="14.28%"><a href="https://gitlab.com/hutson"><img src="https://avatars1.githubusercontent.com/u/6701030?v=4?s=100" width="100px;" alt="Hutson Betts"/><br /><sub><b>Hutson Betts</b></sub></a><br /><a href="#financial-hutson" title="Financial">πŸ’΅</a></td>
1697 <td align="center" valign="top" width="14.28%"><a href="http://lilja.io"><img src="https://avatars2.githubusercontent.com/u/6105119?v=4?s=100" width="100px;" alt="Jonas Lilja"/><br /><sub><b>Jonas Lilja</b></sub></a><br /><a href="#financial-jlilja" title="Financial">πŸ’΅</a> <a href="https://github.com/nock/nock/commits?author=jlilja" title="Code">πŸ’»</a></td>
1698 <td align="center" valign="top" width="14.28%"><a href="https://github.com/benrki"><img src="https://avatars0.githubusercontent.com/u/4446950?v=4?s=100" width="100px;" alt="Benjamin Ki"/><br /><sub><b>Benjamin Ki</b></sub></a><br /><a href="#financial-benrki" title="Financial">πŸ’΅</a></td>
1699 <td align="center" valign="top" width="14.28%"><a href="http://chadf.ca"><img src="https://avatars2.githubusercontent.com/u/3250463?v=4?s=100" width="100px;" alt="Chad Fawcett"/><br /><sub><b>Chad Fawcett</b></sub></a><br /><a href="#financial-chadfawcett" title="Financial">πŸ’΅</a></td>
1700 <td align="center" valign="top" width="14.28%"><a href="http://www.laurencemyers.com.au"><img src="https://avatars.githubusercontent.com/u/6336048?v=4?s=100" width="100px;" alt="Laurence Dougal Myers"/><br /><sub><b>Laurence Dougal Myers</b></sub></a><br /><a href="https://github.com/nock/nock/commits?author=laurence-myers" title="Code">πŸ’»</a></td>
1701 <td align="center" valign="top" width="14.28%"><a href="https://github.com/Beretta1979"><img src="https://avatars.githubusercontent.com/u/10073962?v=4?s=100" width="100px;" alt="SΓ©bastien Van Bruaene"/><br /><sub><b>SΓ©bastien Van Bruaene</b></sub></a><br /><a href="https://github.com/nock/nock/commits?author=Beretta1979" title="Code">πŸ’»</a> <a href="https://github.com/nock/nock/commits?author=Beretta1979" title="Tests">⚠️</a></td>
1702 <td align="center" valign="top" width="14.28%"><a href="https://github.com/Uzlopak"><img src="https://avatars.githubusercontent.com/u/5059100?v=4?s=100" width="100px;" alt="Aras Abbasi"/><br /><sub><b>Aras Abbasi</b></sub></a><br /><a href="https://github.com/nock/nock/commits?author=Uzlopak" title="Code">πŸ’»</a> <a href="https://github.com/nock/nock/commits?author=Uzlopak" title="Tests">⚠️</a> <a href="#maintenance-Uzlopak" title="Maintenance">🚧</a></td>
1703 </tr>
1704 <tr>
1705 <td align="center" valign="top" width="14.28%"><a href="https://github.com/rsaryev"><img src="https://avatars.githubusercontent.com/u/70219513?v=4?s=100" width="100px;" alt="Saryev Rustam"/><br /><sub><b>Saryev Rustam</b></sub></a><br /><a href="https://github.com/nock/nock/commits?author=rsaryev" title="Code">πŸ’»</a> <a href="https://github.com/nock/nock/commits?author=rsaryev" title="Tests">⚠️</a></td>
1706 <td align="center" valign="top" width="14.28%"><a href="https://github.com/mikicho"><img src="https://avatars.githubusercontent.com/u/11459632?v=4?s=100" width="100px;" alt="Michael Solomon"/><br /><sub><b>Michael Solomon</b></sub></a><br /><a href="#maintenance-mikicho" title="Maintenance">🚧</a> <a href="https://github.com/nock/nock/commits?author=mikicho" title="Code">πŸ’»</a> <a href="https://github.com/nock/nock/commits?author=mikicho" title="Documentation">πŸ“–</a></td>
1707 </tr>
1708 </tbody>
1709</table>
1710
1711<!-- markdownlint-restore -->
1712<!-- prettier-ignore-end -->
1713
1714<!-- ALL-CONTRIBUTORS-LIST:END -->
1715
1716This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
1717
1718## Sponsors
1719
1720Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/nock#sponsor)]
1721
1722<a href="https://opencollective.com/nock/sponsor/0/website" target="_blank"><img src="https://opencollective.com/nock/sponsor/0/avatar.svg"></a>
1723<a href="https://opencollective.com/nock/sponsor/1/website" target="_blank"><img src="https://opencollective.com/nock/sponsor/1/avatar.svg"></a>
1724<a href="https://opencollective.com/nock/sponsor/2/website" target="_blank"><img src="https://opencollective.com/nock/sponsor/2/avatar.svg"></a>
1725<a href="https://opencollective.com/nock/sponsor/3/website" target="_blank"><img src="https://opencollective.com/nock/sponsor/3/avatar.svg"></a>
1726<a href="https://opencollective.com/nock/sponsor/4/website" target="_blank"><img src="https://opencollective.com/nock/sponsor/4/avatar.svg"></a>
1727<a href="https://opencollective.com/nock/sponsor/5/website" target="_blank"><img src="https://opencollective.com/nock/sponsor/5/avatar.svg"></a>
1728<a href="https://opencollective.com/nock/sponsor/6/website" target="_blank"><img src="https://opencollective.com/nock/sponsor/6/avatar.svg"></a>
1729<a href="https://opencollective.com/nock/sponsor/7/website" target="_blank"><img src="https://opencollective.com/nock/sponsor/7/avatar.svg"></a>
1730<a href="https://opencollective.com/nock/sponsor/8/website" target="_blank"><img src="https://opencollective.com/nock/sponsor/8/avatar.svg"></a>
1731<a href="https://opencollective.com/nock/sponsor/9/website" target="_blank"><img src="https://opencollective.com/nock/sponsor/9/avatar.svg"></a>
1732
1733## License
1734
1735[MIT](LICENSE)
1736
1737Copyright (c) 2011–2019 [Pedro Teixeira](http://about.me/pedroteixeira) and other [contributors](https://github.com/nock/nock/graphs/contributors).