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!