You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Mock http requests made using fetch (or isomorphic-fetch)
3
3
4
-
*notes*
4
+
*notes*
5
5
- When using isomorphic-fetch or node-fetch ideally `fetch` should be added as a global. If not possible to do so you can still use fetch-mock in combination with [mockery](https://github.com/mfncooper/mockery) in nodejs (see `useNonGlobalFetch(func)` below)
6
6
- fetch-mock doesn't declare `fetch` or `Promise` as dependencies; as you're testing `fetch` it's assumed you're already taking care of these globals
7
7
- fetch-mock uses [npm debug](https://www.npmjs.com/package/debug). To output useful messages for debugging set the environment variable `DEBUG=fetch-mock`
8
-
- If you prefer documentation by example skip to the bottom of this README
9
-
- To use fetch-mock on the server simply `npm install fetch-mock` and `require('fetch-mock)`. In the browser either
8
+
- To use fetch-mock on the server simply `npm install fetch-mock` and `require('fetch-mock)`. In the browser either
10
9
- use browserify + debowerify and both `npm install fetch-mock` and `bower install fetch-mock`, then use `require('fetch-mock)`
11
10
- use browserify and `npm install fetch-mock` and `require('fetch-mock/client)`
12
11
13
-
## API
14
-
15
-
`require('fetch-mock')` exports a singleton with the following methods
16
-
17
-
### `mock(config)`
18
-
Replaces `fetch()` with a sinon stub which, in addition to the default sinon behaviour, records it's calls, grouped by route, and optionally returns a stub response or passes the call through to `fetch()`. `config` is an optional* object with the following properties.
19
-
20
-
*`routes`: Either a single object or an array of similar objects each defining how the mock handles a given request. If multiple routes are specified the first matching route will be used to define the response. Each route object must have the following properties.
21
-
* `name`: A unique string naming the route
22
-
* `matcher`: The rule for matching calls to `fetch()`. Accepts any of the following
23
-
* `string`: Either an exact url to match e.g. 'http://www.site.com/page.html' or, if the string begins with a `^`, the string following the `^` must begin the url e.g. '^http://www.site.com' would match 'http://www.site.com' or 'http://www.site.com/page.html'
24
-
* `RegExp`: A regular expression to test the url against
25
-
* `Function(url, opts)`: A function that is passed the url and opts `fetch()` is called with and that returns a Boolean
26
-
* `response`: Configures the response object returned by the mock. Can take any of the following values
27
-
* `number`: creates a response with the number as the response status
28
-
* `string`: creates a 200 response with the string as the response body
29
-
* `object`: If the object contains any of the properties body, status, headers, throws; then these properties - all of them optional - are used to construct a response as follows
30
-
* `body`: Returned in the response body
31
-
* `status`: Returned in the response status
32
-
* `headers`: Returned in the response headers. They should be defined as an object literal (property names case-insensitive) which will be converted to a `Headers` instance
33
-
* `throws`: If this property is present then a `Promise` rejected with the value of `throws` is returned
34
-
35
-
As long as the object does not contain any of the above properties it is converted into a json string and this is returned as the body of a 200 response
36
-
* `Function(url, opts)`: A function that is passed the url and opts `fetch()` is called with and that returns any of the responses listed above
37
-
*`responses`: When `registerRoute()` has already been used to register some routes then `responses` can be used to override the default response. Its value should be an object mapping route names to responses, which should be similar to those listed immediately above e.g.
38
-
39
-
```javascript
40
-
responses: {
41
-
session:function (url, opts) {
42
-
if (opts.headers.authorized) {
43
-
return {user:'dummy-authorized-user'};
44
-
} else {
45
-
return {user:'dummy-unauthorized-user'};
46
-
}
47
-
}
48
-
}
49
-
```
50
-
51
-
*`greed`: Determines how the mock handles unmatched requests
52
-
* 'none': all unmatched calls get passed through to `fetch()`
53
-
* 'bad': all unmatched calls result in a rejected promise
54
-
* 'good': all unmatched calls result in a resolved promise with a 200 status
55
-
56
-
57
-
\*`config` is optional only when preconfigured routes have already been setup
58
-
59
-
60
-
### `restore()`
61
-
Restores `fetch()` to its unstubbed state and clears all data recorded for its calls
62
-
63
-
### `reset()`
64
-
Clears all data recorded for `fetch()`'s calls
65
-
66
-
### `calls(routeName)`
67
-
Returns an array of arrays of the arguments passed to `fetch()` that matched the given route. '__unmatched' can be passed in to return results for calls not matching any route.
68
-
69
-
### `called(routeName)`
70
-
Returns a Boolean denoting whether any calls matched the given route. '__unmatched' can be passed in to return results for calls not matching any route. If no routeName is passed it returns `true` if any fetch calls were made
71
-
72
-
### `reMock()`
73
-
Normally calling `mock()` twice without restoring inbetween will throw an error. `reMock()` calls `restore()` internally before calling `mock()` again. This allows you to put a generic call to `mock()` in a `beforeEach()` while retaining the flexibility to vary the responses for some tests
74
-
75
-
### `registerRoute(name, matcher, response)`
76
-
Often your application/module will need a mocked response for some http requests in order to initialise properly, even if the content of those calls are not the subject of a given test e.g. a mock response from an authentication service and a multi-variant testing service might be necessary in order to test the UI for a version of a log in form. It's helpful to be able to define some default responses for these services which will exist throughout all or a large subset of your tests. `registerRoute()` aims to fulfil this need. All these predefined routes can be overridden when `mock(config)` is called.
77
-
78
-
`registerRoute()` takes either of the following parameters
79
-
*`object`: An object similar to the route objects accepted by `mock()`
80
-
*`array`: An array of the above objects
81
-
*`name`, `matcher`, `response`: The 3 properties of the route object spread across 3 parameters
82
-
83
-
### `unregisterRoute(name)`
84
-
Unregisters one or more previously registered routes. Accepts either a string or an array of strings
85
-
86
-
### `useNonGlobalFetch(func)`
87
-
To use fetch-mock with with [mockery](https://github.com/mfncooper/mockery) you will need to use this function to prevent fetch-mock trying to mock the function globally.
88
-
*`func` Optional reference to `fetch` (or any other function you may want to substitute for `fetch` in your tests). This will be converted to a `sinon.stub` and can be accessed via `fetchMock.fetch`
89
-
90
-
#### Mockery example
91
-
```javascript
92
-
var fetch =require('node-fetch');
93
-
var fetchMock =require('fetch-mock');
94
-
var mockery =require('mockery');
95
-
fetchMock.useNonGlobalFetch(fetch);
96
-
97
-
fetchMock.registerRoute([
98
-
...
99
-
])
100
-
it('should make a request', function (done) {
101
-
mockery.registerMock('fetch', fetchMock.mock());
102
-
// test code goes in here
103
-
mockery.deregisterMock('fetch');
104
-
done();
105
-
});
106
-
107
-
```
108
-
109
-
## Example
12
+
## Example
110
13
```javascript
111
14
112
15
var fetchMock =require('fetch-mock');
113
16
114
-
//Set up some routes you will always want to mock
17
+
//Optionally set up some routes you will always want to mock
115
18
// Accepts an array of config objects or three parameters,
116
19
// name, matcher and response, to add a single route
117
20
fetchMock.registerRoute([
@@ -149,12 +52,12 @@ it('should do A', function () {
149
52
// none: all unmatched calls get sent straight through to the default fetch
150
53
// bad: all unmatched calls result in a rejected promise
151
54
// good: all unmatched calls result in a resolved promise with a 200 status
152
-
greed:'none'
55
+
greed:'none'
153
56
});
154
-
57
+
155
58
thingToTest.exec();
156
59
157
-
// returns an array of calls to the session service,
60
+
// returns an array of calls to the session service,
158
61
// each item in the array is an array of the arguments passed to fetch
159
62
// similar to sinon.spy.args
160
63
fetchMock.calls('session') // non empty array
@@ -165,7 +68,7 @@ it('should do A', function () {
165
68
166
69
fetchMock.calls('session') // undefined
167
70
fetchMock.called('geo') // false
168
-
71
+
169
72
// fetch itself is just an ordinary sinon.stub
170
73
fetch.calledWith('thing')
171
74
@@ -186,11 +89,11 @@ describe('content', function () {
186
89
})
187
90
188
91
it('should do B', function () {
189
-
190
-
92
+
93
+
191
94
fetchMock.mock({
192
95
// you can choose to mock a subset of the registered routes
193
-
// and even add one to be mocked for this test only
96
+
// and even add one to be mocked for this test only
194
97
// - the route will exist until fetchMock.restore() is called
195
98
routes: ['session', 'content', {
196
99
name:'enhanced-content',
@@ -202,29 +105,29 @@ describe('content', function () {
202
105
}
203
106
}]
204
107
});
205
-
108
+
206
109
thingToTest.exec();
207
110
208
111
fetchMock.calls('content') // non empty array
209
112
fetchMock.called('enhanced-content') // Boolean
210
-
113
+
211
114
// restores fetch and resets all data
212
115
fetchMock.restore();
213
116
})
214
117
215
118
it('should do C', function () {
216
-
217
-
119
+
120
+
218
121
fetchMock.mock({
219
122
// you can override the response for a service for this test only
220
-
// this means e.g. you can configure an authentication service to return
123
+
// this means e.g. you can configure an authentication service to return
221
124
// a valid user normally, but only return invalid for the one test
222
125
// where you're testing authentication
223
126
responses: {
224
127
'session':'invalid-user'
225
128
}
226
129
});
227
-
130
+
228
131
thingToTest.exec();
229
132
230
133
// restores fetch and resets all data
@@ -233,3 +136,101 @@ describe('content', function () {
233
136
234
137
});
235
138
```
139
+
140
+
141
+
142
+
## API
143
+
144
+
`require('fetch-mock')` exports a singleton with the following methods
145
+
146
+
### `mock(config)`
147
+
Replaces `fetch()` with a sinon stub which, in addition to the default sinon behaviour, records it's calls, grouped by route, and optionally returns a stub response or passes the call through to `fetch()`. `config` is an optional* object with the following properties.
148
+
149
+
*`routes`: Either a single object or an array of similar objects each defining how the mock handles a given request. If multiple routes are specified the first matching route will be used to define the response. Each route object must have the following properties.
150
+
* `name`: A unique string naming the route
151
+
* `matcher`: The rule for matching calls to `fetch()`. Accepts any of the following
152
+
* `string`: Either an exact url to match e.g. 'http://www.site.com/page.html' or, if the string begins with a `^`, the string following the `^` must begin the url e.g. '^http://www.site.com' would match 'http://www.site.com' or 'http://www.site.com/page.html'
153
+
* `RegExp`: A regular expression to test the url against
154
+
* `Function(url, opts)`: A function that is passed the url and opts `fetch()` is called with and that returns a Boolean
155
+
* `response`: Configures the response object returned by the mock. Can take any of the following values
156
+
* `number`: creates a response with the number as the response status
157
+
* `string`: creates a 200 response with the string as the response body
158
+
* `object`: If the object contains any of the properties body, status, headers, throws; then these properties - all of them optional - are used to construct a response as follows
159
+
* `body`: Returned in the response body
160
+
* `status`: Returned in the response status
161
+
* `headers`: Returned in the response headers. They should be defined as an object literal (property names case-insensitive) which will be converted to a `Headers` instance
162
+
* `throws`: If this property is present then a `Promise` rejected with the value of `throws` is returned
163
+
164
+
As long as the object does not contain any of the above properties it is converted into a json string and this is returned as the body of a 200 response
165
+
* `Function(url, opts)`: A function that is passed the url and opts `fetch()` is called with and that returns any of the responses listed above
166
+
*`responses`: When `registerRoute()` has already been used to register some routes then `responses` can be used to override the default response. Its value should be an object mapping route names to responses, which should be similar to those listed immediately above e.g.
167
+
168
+
```javascript
169
+
responses: {
170
+
session:function (url, opts) {
171
+
if (opts.headers.authorized) {
172
+
return {user:'dummy-authorized-user'};
173
+
} else {
174
+
return {user:'dummy-unauthorized-user'};
175
+
}
176
+
}
177
+
}
178
+
```
179
+
180
+
*`greed`: Determines how the mock handles unmatched requests
181
+
* 'none': all unmatched calls get passed through to `fetch()`
182
+
* 'bad': all unmatched calls result in a rejected promise
183
+
* 'good': all unmatched calls result in a resolved promise with a 200 status
184
+
185
+
186
+
\*`config` is optional only when preconfigured routes have already been setup
187
+
188
+
189
+
### `restore()`
190
+
Restores `fetch()` to its unstubbed state and clears all data recorded for its calls
191
+
192
+
### `reset()`
193
+
Clears all data recorded for `fetch()`'s calls
194
+
195
+
### `calls(routeName)`
196
+
Returns an array of arrays of the arguments passed to `fetch()` that matched the given route. '__unmatched' can be passed in to return results for calls not matching any route.
197
+
198
+
### `called(routeName)`
199
+
Returns a Boolean denoting whether any calls matched the given route. '__unmatched' can be passed in to return results for calls not matching any route. If no routeName is passed it returns `true` if any fetch calls were made
200
+
201
+
### `reMock()`
202
+
Normally calling `mock()` twice without restoring inbetween will throw an error. `reMock()` calls `restore()` internally before calling `mock()` again. This allows you to put a generic call to `mock()` in a `beforeEach()` while retaining the flexibility to vary the responses for some tests
203
+
204
+
### `registerRoute(name, matcher, response)`
205
+
Often your application/module will need a mocked response for some http requests in order to initialise properly, even if the content of those calls are not the subject of a given test e.g. a mock response from an authentication service and a multi-variant testing service might be necessary in order to test the UI for a version of a log in form. It's helpful to be able to define some default responses for these services which will exist throughout all or a large subset of your tests. `registerRoute()` aims to fulfil this need. All these predefined routes can be overridden when `mock(config)` is called.
206
+
207
+
`registerRoute()` takes either of the following parameters
208
+
*`object`: An object similar to the route objects accepted by `mock()`
209
+
*`array`: An array of the above objects
210
+
*`name`, `matcher`, `response`: The 3 properties of the route object spread across 3 parameters
211
+
212
+
### `unregisterRoute(name)`
213
+
Unregisters one or more previously registered routes. Accepts either a string or an array of strings
214
+
215
+
### `useNonGlobalFetch(func)`
216
+
To use fetch-mock with with [mockery](https://github.com/mfncooper/mockery) you will need to use this function to prevent fetch-mock trying to mock the function globally.
217
+
*`func` Optional reference to `fetch` (or any other function you may want to substitute for `fetch` in your tests). This will be converted to a `sinon.stub` and can be accessed via `fetchMock.fetch`
0 commit comments