Mocking Firebase Cloud Functions in React.js with Jest
I am a beginner in Web Development and I finally decided to learn how to test my apps. I had a simple application with the common stack React.js, Webpack and Babel, plus Firebase Cloud Functions for the back-end. I decided to go for testing with Jest and React Testing Library and I started by following this tutorial https://www.leveluptutorials.com/tutorials/react-testing-for-beginners, which was pretty good to get solid start. I followed the whole tutorial but I run into troubles when I wanted to do integration test and I had to mock the cloud functions: the test would not call the cloud functions, and anyway it would be better to mock any API calls. After going through the Jest documentation and various Stack Overflow posts I reached a working solution, which I illustrate below.
First the real code we are going to mock
Here the example of the real cloud function we are going to mock, stored somewhere separate from the front-end code and loaded into Google Firebase Cloud Function service:
const functions = require(‘firebase-functions’);
const admin = require(‘firebase-admin’);admin.initializeApp();exports.cloudFunction = functions.https.onCall((data, context) => {
try {…. do something here…
values = {
returnValueOne: ‘valueOne’,
returnValueTwo: ‘valueTwo’,
}
} catch(err) {
throw new functions.https.HttpsError(err.code, err.message, err.details)
}
return { values }
});
This is the real (not mock!) firebase.js
file:
const firebase = require(‘firebase’);
require(‘firebase/functions’);const config = {
<ALL YOUR CONFIG HERE>
};
firebase.initializeApp(config);// Initialize Cloud Functions through Firebase
const functions = firebase.functions();export default functions;
This is how I would call the cloud function in the code:
import functions from ‘../../firebase’;
…some code here…const cloudFunction = functions.httpsCallable(‘cloudFunction’);
cloudFunction({ data })
.then(result => doSomethingWithResult(result.data.values))
.catch((err) => {
setModal({ open: true, message: err.message });
});…some code here…
The solution with the mock code
The solution is based on the Jest Manual Mocks for Node modules (https://jestjs.io/docs/en/manual-mocks). First create the __mocks__
(case sensitive) directory, which has to be adjacent to node_modules
directory, then inside __mocks__
create firebase.js
which is going to mock the firebase module and contain the mock function.
The content of /__mocks__/firebase.js
:
const firebase = jest.genMockFromModule(‘firebase’);firebase.initializeApp = jest.fn();const values = {
returnValueOne: ‘valueOne’,
returnValueTwo: ‘valueTwo’,
};const data = {
values,
};const cloudFunction = jest.fn((testValues) => {
if (testValues.value === ‘Valid value’) {
return Promise.resolve({
data,
});
}
return Promise.reject(new Error(‘Error message’));
});const httpsCallable = jest.fn(() => cloudFunction);firebase.functions = jest.fn(() => ({
httpsCallable,
}));module.exports = firebase;
I have a file where I keep all the test runs __tests__/app.test.jsx
and now when I simulate the click on the button firing the call to the cloud function, Jest runs the mock firebase with the mock function. Here is an example of the test file:
That is it, I could not find a tutorial about this topic when I needed it, so I hope this can be useful to other web developers. If this tutorial helped you, you can thank me by buying me coffee.