Forbes magazine logo Ranked Best Coding Bootcamps 2023

Mocking node environment fetch() function using Jest.

Altcademy Team wrote on 7 February 2018

I am developing a node client which is a library consuming an API. The various functions return a Promise using the fetch() function. The npm package I use is 'isomorphic-fetch' and I am trying to mock the fetch function using Jest testing framework. The problem seems to be around mocking the fetch() function in a "node" environment rather than a browser environment. If you guys can crack this - you're very smart. Haha :) good luck!

// package.json { "name": "", "version": "2.0.0", "description": "node client to communicate with permissions API", "main": "src/index.js", "scripts": { "lint": "eslint src/", "test": "jest", "compile": "babel src -s -D -d lib --ignore /__tests__/", "prepublish": "npm run compile" }, "author": "Dominic Dunnett", "license": "ISC", "devDependencies": { "babel-cli": "^6.16.0", "babel-core": "^6.17.0", "babel-eslint": "^7.0.0", "babel-preset-es2015": "^6.16.0", "eslint": "^3.7.1", "eslint-config-airbnb": "^12.0.0", "eslint-plugin-import": "^1.16.0", "eslint-plugin-jasmine": "^1.8.1", "eslint-plugin-jsx-a11y": "^2.2.2", "eslint-plugin-react": "^6.3.0", "fetch-mock": "^5.5.0", "jest": "^16.0.1", "pre-commit": "^1.1.3" }, "jest": { "scriptPreprocessor": "<rootDir>/node_modules/babel-jest", "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(es6|js|json)$", "testPathDirs": [ "src" ], "moduleFileExtensions": [ "js", "json", "es6" ], "testEnvironment": "node" }, "pre-commit": [ "lint" ], "dependencies": { "es6-promise": "^4.0.5", "isomorphic-fetch": "^2.2.1", "request": "^2.75.0" } } // This is the simplified function i'm trying to test const url = require('url'); const fetch = require('isomorphic-fetch'); function performFetch(endpoint, data = false) { return fetch(endpoint) .then((response) => { if (data) { return filterStatus(response.status, response.json()); } return filterStatus(response.status); }) .catch((error) => { throw error; }); } // This is the test I am looking for const fetchMock = require('fetch-mock'); fetchMock.mock('*', { foo: 'bar' }); it('should call the api', () => { performFetch('http://google.com'); expect(fetchMock.called()).toBe(true) });

@Dom, here are the issues. performFetch is an async function so when expect(fetchMock.called()).toBe(true) is run fetchMock hasn't been called yet. You need to place the test inside a then function after performFetch or use async/await to write the tests. More on async/await here https://facebook.github.io/jest/docs/tutorial-async.html#async-await

The other one is how you required isomorphic-fetch;

https://github.com/wheresrhys/fetch-mock#fetch-doesnt-seem-to-be-getting-mocked

If using isomorphic-fetch in your source, are you assigning it to a fetch variable? You shouldn't be i.e.
import 'isomorphic-fetch', not import fetch from 'isomorphic-fetch'
require('isomorphic-fetch'), not const fetch = require('isomorphic-fetch')
Here is my working code:
require('isomorphic-fetch'); const url = require('url'); const fetchMock = require('fetch-mock'); function filterStatus(status, data) { if (data) { return data; } else { return true; } } function performFetch(endpoint, data) { return fetch(endpoint) .then((response) => { if (data) { return filterStatus(response.status, response.json()); } return filterStatus(response.status); }) .catch((error) => { throw error; }); } fetchMock.mock('*', { foo: 'bar' }); it('should call the api', () => { return performFetch('http://google.com', false) .then(response => { console.log('fetchMock.called():', fetchMock.called()); expect(fetchMock.called()).toBe(true); }) });


what error are you getting?

Error below:

require('isomorphic-fetch'); const url = require('url'); const fetchMock = require('fetch-mock'); const utils = require('../utils/utils.js'); fetchMock.mock('*', { foo: 'bar' }); describe('Utils Module', () => { describe('#hasRequiredParams', () => { it('should call the api', () => { return utils.performFetch('http://google.com', false) .then(() => { console.log('fetchMock.called():', fetchMock.called()); expect(fetchMock.called()).toBe(true); }); }); }); });

can i see your utils.js? My guess is the require isomorphic-fetch there isn't fixed.
you don't need to have require isomorphic-fetch in the test file.

that was it! Thanks guys - had this in my utils.js:

const url = require('url'); const fetch = require('isomorphic-fetch');

Now working - thanks for the help!

Trusted by

Students and instructors from world-class organizations

Imperial College London
Carnegie Mellon University
City University of Hong Kong
Hack Reactor
Cisco Meraki
University of Oxford
Swift
Bazaarvoice
Waterloo
Uber
AtlanTech
Tumblr
Boston College
Bombardier Aerospace
University of St. Andrews
New York University
Minerva Schools at KGI
Merrill Lynch
Riot Games
JP Morgan
Morgan Stanley
Advanced Placement®
Google
KPMG
The University of Hong Kong
University of Toronto
SCMP
Moat
Zynga
Hello Toby
Deloitte
Goldman Sachs
Yahoo
HSBC
General Assembly
Tesla
McGill University
Microsoft

Join the upcoming Cohort #89

Enroll for May 6th, 2024