Security News
38% of CISOs Fear They’re Not Moving Fast Enough on AI
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
jest-mock-fetch
Advanced tools
This is a ultra light-weight synchronous fetch
mock for unit testing with Jest.
It can be used to mock the native fetch
or 3rd party libraries such as unfetch
.
Module verion 2.0.0 was intended to make this mock more in-line with the official fetch API.
This however brings some braking changes:
fetch
function now has only two arguments (resource
and init
) instead of three (url
, data
, config
)mockResult
no longer accepts data
param - you now need to provide implementation to some of the usuall response methods (i.e. text
, json
, etc)Please update your code accordingly.
Installation is simple - just run:
npm i --save-dev jest-mock-fetch
fetch
Create a setupJest.js
file to setup the mock with the folloging content:
// setupJest.js
global.fetch = require('jest-mock-fetch');
Edit the jest.config.js
file and add the following:
"jest": {
"automock": false,
"setupFiles": [
"./setupJest.js"
]
}
If you are using a polyfill/ponyfill library (i.e. unfetch) which implement fetch
API then you need to use a different setup procedure.
Here's an example for unfetch:
__mocks__
directory in your project rootunfetch.js
unfetch.js
file
// ./__mocks__/unfetch.js
import unfetch from 'jest-mock-fetch';
export default unfetch;
Let's consider that we want to test a component which uses fetch
. This component returns a promise, which will be resolved after fetch
is done communicating with the server.
Here's a Jest snippet, which explains how we would test this component:
// ./test/UppercaseProxy.spec.js
import UppercaseProxy from '../src/UppercaseProxy';
import fetch from 'jest-mock-fetch';
afterEach(() => {
// cleaning up the mess left behind the previous test
fetch.reset();
});
it('UppercaseProxy should get data from the server and convert it to UPPERCASE', () => {
let catchFn = jest.fn(),
thenFn = jest.fn();
// using the component, which should make a server response
let clientMessage = 'client is saying hello!';
UppercaseProxy(clientMessage)
.then(thenFn)
.catch(catchFn);
// since `post` method is a spy, we can check if the server request was correct
// a) the correct method was used (post)
// b) went to the correct web service URL ('/web-service-url/')
// c) if the payload was correct ('client is saying hello!')
expect(fetch).toHaveBeenCalledWith("/web-service-url/", {
body: clientMessage,
});
// simulating a server response
fetch.mockResponse({
text: () => 'server says hello!'
});
// checking the `then` spy has been called and if the
// response from the server was converted to upper case
expect(thenFn).toHaveBeenCalledWith('SERVER SAYS HELLO!');
// catch should not have been called
expect(catchFn).not.toHaveBeenCalled();
});
To make this example complete and easier to understand, let's have a look at a (verbose) implementation of component we are testing:
// ./src/UppercaseProxy.js
const UppercaseProxy = (clientMessage) => {
return(
// requesting data from server
fetch('/web-service-url/', { body: clientMessage })
// get the response text
.then(response => response.text())
// convert text to uppercase
.then(text => text.toUpperCase())
);
};
export default UppercaseProxy;
At the bottom of this page you can find additional examples.
fetch
mock APIIn addition to mock fetch
itself being a spy, it also has additional public methods, which are intended to facilitate mocking:
mockResponse
- simulates a server (web service) responsemockError
- simulates a (network/server) errorlastReqGet
- returns extended info about the most recent requestlastPromiseGet
- returns promise created when the most recent request was madereset
- resets the fetch
mock object - prepare it for the next test (typically used in afterEach
)After a request has been made to the server (web service), this method resolves that request by simulating a server response. Status meaning is ignored, i.e. 400
will still resolve fetch
promise. Use mockError
for non-2xx responses.
NOTE: This method should be called after the fetch call in your test for the promise to resolve properly. After all remember that this mock works synchronously.
response
The first argument of this method is the a response object returned by the server, with a structure illustrated by the snippet below. All the properties are optional, meaning that if a property is ommitted it will be replaced by a default value (defaults are shown in the snippet).
response = {
body: new PassThrough(),
headers: new Headers(),
status: 200,
statusText: "OK",
ok: true,
url: resource as string,
arrayBuffer: () => new ArrayBuffer(0),
blob: () => new Blob(),
clone: jest.fn(),
error: jest.fn(),
formData: () => new FormData(),
json: () => ({ }),
redirect: jest.fn(),
text: () => "dummy text"
}
The given response object will get passed to then
even handler function.
item
The second argument enables us to pinpoint an exact server request we wish to resolve. This can be useful if we're making multiple server requests and are planing to resolve them in a different order from the one in which they were made.
We can supply two different objects:
lastReqGet
methodpromise
object, which is can be accessed by calling the lastPromiseGet
methodIf ommited this argument defaults to the latest request made (internally the lastReqGet
method is called).
At the end of this document you can find an example which demonstrates how this parameter can be used.
silentMode
Both mockResponse
and mockError
will throw an error if there's no pending request to resolve/reject.
You can change this behavior by passing true
as third argument, activating the so-called silentMode
. With silentMode
activated, the methods will just do nothing.
This method simulates an error while making a server request (network error, server error, etc ...).
NOTE: This method should be called after the fetch call in your test for the promise to resolve properly. After all remember that this mock works synchronously.
err
Error object will get passed to catch
event handler function. If omitted it defaults to an empty object.
item
The second argument is a item
object, which works the same way as described part about the mockResponse
method.
silentMode
The third argument is the silentMode
flag, which works the same way as described part about the mockResponse
method.
lastReqGet
method returns extended info about the most recent request. The returned value can be used to pinpoint exact server request we wish to resolve (the value is passed as the second param of mockResponse
or mockError
methods).
The returned info contains all the data relevant to the request. It has the following structure (an example):
let requestInfo = {
// promise created while
promise: SimplePromise,
// URL passed to the fetch
resource: "https://github.com/",
// payload sent to server
init: { body: "this is payload sent to the server" },
}
Additional examples at the end of this document illustrate how this method can be used.
NOTE: this is a sibling method to the lastPromiseGet
(which returns only the promise portion of this the request object).
getReqByUrl()
returns the same info about a specific request as lastReqGet
(see above). Instead of returning the
most recent request, it returns the most recent request matching the given url.
url
The url to be matched. Must match exactly the url passed to fetch before.
lastPromiseGet
method returns a promise given when the most recent server request was made. The returned value can be used to pinpoint exact server request we wish to resolve (the value is passed as the second param of mockResponse
or mockError
methods).
Additional examples at the end of this document illustrate how this method can be used.
NOTE: This is a sibling method to the lastReqGet
, which in addition to promise returns object containing extended info about the request.
reset
method clears state of the fetch
mock to initial values. It should be called after each test, so that we can start fresh with our next test (i.e. from afterEach
method).
Since fetchMock is relatively simple, most of its functionality was covered in basic example at the beginning of this document. In this section we'll explore features not covered by that initial example.
lastReqGet
and lastPromiseGet
methodsThe following example illustrates the meaning of the values returned by lastReqGet
and lastPromiseGet
methods.
The first snippet shows a component which will be tested. The component makes a request to the server and stores the promise returned by fetch
.
// ./src/MyComponent.js
class MyComponent {
CallServer () {
// making a request and storing the given promise
this.fetchPromise = fetch('/web-service-url/', { data: clientMessage });
}
}
export default MyComponent;
In our spec file we will compare promise stored inside the MyComponent
with values returned by lastReqGet
and lastPromiseGet
methods:
// ./test/MyComponent.spec.js
import MyComponent from '../src/SomeSourceFile';
let myComp = new MyComponent();
myComp.CallServer();
// getting the extended info about the most recent request
let lastReqInfo = fetch.lastReqGet();
// getting the promise made when the most recent request was made
let lastPromise = fetch.lastPromiseGet();
// the following expression will write `true` to the console
// > here we compare promise stored in the `MyComponent` to the one
// returned by the `lastPromiseGet` method
console.log(myComp.fetchPromise === lastPromise);
// the following expression will also write `true` to the console
// > here we compare promise stored in the `MyComponent`
// to the one in the request info, which was returned by the
// `lastReqGet` method
console.log(myComp.fetchPromise === lastReqInfo.promise);
// the following will also write "true" to console,
// since it't the same object
console.log(lastPromise === lastReqInfo.promise);
In the following example we'll have a look at how to resolve requests at desired order by using lastReqGet
method.
In this example we'll create two consecutive requests before simulating a server response to the first one.
it('when resolving a request an appropriate handler should be called', () => {
let thenFn1 = jest.fn(),
thenFn2 = jest.fn();
// creating the FIRST server request
UppercaseProxy('client is saying hello!').then(thenFn1);
// storing the request info - we'll need it later to pinpoint the request
let firstRequestInfo = fetch.lastReqGet();
// creating the SECOND server request
// BEFORE the first had chance to be resolved
UppercaseProxy('client says bye bye!').then(thenFn2);
// Simulating a server response to the FIRST request
// -> we're using request info object to pinpoint the request
// ... IF the info object is ommited, the method would automatically
// resolve to the newest request from the internal queue (the SECOND one)
const firstResponse = fetch.mockResponse({ text: () => 'server says hello!' }, firstRequestInfo);
// only the first handler should have been called
expect(thenFn1).toHaveBeenCalled();
expect(thenFn2).not.toHaveBeenCalled();
// Simulating a server response to the SECOND request
// NOTE: here we don't need to provide the request info,
// since there is only one unresolved request left
// -> `mockResponse` resolves the last request in the
// queue if request info is ommited
fetch.mockResponse({ data: 'server says bye bye!' });
// the first `then` handles should be called only once
expect(thenFn1).toHaveBeenCalledTimes(1);
// now the second `then` handler should be called
expect(thenFn2).toHaveBeenCalled();
});
Although this might not be the most realistic use-case of this functionality, it does illustrate how lastReqGet
method can be used to alter the default behaviour of the mockResponse
method.
NOTE: the identical effect can be achieved by using the lastPromiseGet
method. These two methods perform a similar task, as described in the corresponding documentation.
The magic which enables fetch mock to work synchronously is hidden away in jest-mock-promise
, which enables promises to be settled in synchronous manner.
This mock is based on: jest-mock-axios
MIT License, http://www.opensource.org/licenses/MIT
FAQs
Synchronous `fetch` mock for Jest
The npm package jest-mock-fetch receives a total of 0 weekly downloads. As such, jest-mock-fetch popularity was classified as not popular.
We found that jest-mock-fetch demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.
Security News
Company News
Socket is joining TC54 to help develop standards for software supply chain security, contributing to the evolution of SBOMs, CycloneDX, and Package URL specifications.