12

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.

1 Answer 1

12

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

Sign up to request clarification or add additional context in comments.

2 Comments

Does the automock setting in Jest affect this at all?
@jcollum I believe it needs to be set to false

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.