I am trying to create Response Objects for mocking with jest, I can't seem to get the right syntax.
Initialization,
jest.mock('node-fetch')
const fetch = require('node-fetch')
const { Response, Headers } = jest.requireActual('node-fetch')
// Example adapted from https://fetch.spec.whatwg.org/#example-headers-class
const meta = {
'Content-Type': 'application/json',
'Accept': '*/*',
'Breaking-Bad': '<3'
}
// You can in fact use any iterable objects, like a Map or even another Headers
const headers = new Headers(meta)
const copyOfHeaders = new Headers(headers)
const ResponseInit = {
status: 200,
statusText: 'fail',
headers: headers
}
With a basic test
test('Basic Test', async () => {
const token = ''
const getDocList = new Response(JSON.stringify(downloadDocumentData), ResponseInit)
fetch.mockResolvedValueOnce(Promise.resolve(getDocList))
await module.doSomething('mock', token)
.then( async(res) => {
await expect(res.data).toEqual(Object)
})
}, 5000)
I'm getting an error which is
FetchError {
message:
'invalid json response body at reason: Unexpected token H in JSON at position 2',
type: 'invalid-json' }
How can I initial a response for valid json, I have tried a lot of different things.
Following the article at https://jestjs.io/docs/en/bypassing-module-mocks but I want to return and test json instead.
We should use jest.mock(moduleName, factory, options) to mock node-fetch
module and fetch
function.
In order to construct the response object of the fetch
function, you need to use the Response
class provided by the node-fetch
module, so use jest.requireActual(moduleName) to get the original, unmocked node-fetch
Module and Response
class.
Of course, we can construct the response object arbitrarily, but the instance of the Response
class is really close to the real response.
The same goes for headers
object.
Here is a working demo:
index.js
:
const fetch = require('node-fetch');
module.exports = {
async doSomething(url, token) {
return fetch(url).then(res => res.json());
}
};
index.spec.js
:
jest.mock('node-fetch');
const fetch = require('node-fetch');
const { Response, Headers } = jest.requireActual('node-fetch');
const mod = require('./');
const meta = {
'Content-Type': 'application/json',
Accept: '*/*',
'Breaking-Bad': '<3'
};
const headers = new Headers(meta);
const copyOfHeaders = new Headers(headers);
const ResponseInit = {
status: 200,
statusText: 'fail',
headers: headers
};
test('Basic Test', async () => {
const token = '';
const downloadDocumentData = { data: {} };
const getDocList = new Response(
JSON.stringify(downloadDocumentData),
ResponseInit
);
fetch.mockResolvedValueOnce(Promise.resolve(getDocList));
const res = await mod.doSomething('mock', token);
expect(res).toEqual({ data: {} });
expect(fetch).toBeCalledWith('mock');
});
Unit test result:
PASS src/stackoverflow/58648691/index.spec.js
✓ Basic Test (5ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.557s
Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58648691