I have a series of functions, each performing various firestore interactions. How do I use Jest to mock these firestore calls? I would like to avoid using a library.
I used the dependancy injection approach on components and it meant I could mock and test methods without all the boilerplate.
For example, I have a form component that handles invites like so:
import React, { useEffect } from 'react';
import { Formik } from 'formik';
import { validations } from '../../helpers';
import { checkIfTeamExists } from '../helpers';
const Invite = ({ send, userEmail, handleTeamCreation, auth, db, dbWhere }) => {
useEffect(() => {
checkIfTeamExists(send, dbWhere);
}, []);
return (
handleTeamCreation(userEmail, values.email, db, auth, send)
}
validate={validations}
render={props => (
)}
/>
);
};
export default Invite;
The checkIfTeamExists method relies on firebase auth and handleTeamCreation method writes to the firestore.
When I referenced the component in its parent I instantiated it like so:
Then, using react-testing-library, in my tests I was able to mock things out with a simple jest.fn().
test('Invite form fires the send function on Submit ', async () => {
const handleTeamCreation = jest.fn();
const send = jest.fn();
const userEmail = 'ex@mple.com';
const db = jest.fn();
const auth = jest.fn();
const dbWhere = jest.fn().mockResolvedValue([]);
const { getByPlaceholderText, getByTestId } = render(
);
const inputNode = getByPlaceholderText('Please enter your email.');
const email = 'me@gmail.com';
fireEvent.change(inputNode, { target: { value: email } });
const formNode = getByTestId('form');
fireEvent.submit(formNode);
await wait(() => {
expect(handleTeamCreation).toHaveBeenCalledWith(
userEmail,
email,
db,
auth,
send
);
expect(handleTeamCreation).toHaveBeenCalledTimes(1);
});
});
and mocked the firestore where query in the same way.
test('Invite form must contain a valid email address', async () => {
const send = jest.fn();
const db = jest.fn();
const dbWhere = jest.fn().mockResolvedValue([]);
const { getByPlaceholderText, queryByTestId } = render(
);
expect(queryByTestId('error')).not.toBeInTheDocument();
const inputNode = getByPlaceholderText('Please enter your email.');
const email = 'x';
fireEvent.change(inputNode, { target: { value: email } });
await wait(() => {
expect(queryByTestId('error')).toHaveTextContent('Invalid email address');
});
});
This is very simple, but it works. It's also quite verbose but I thought a real use case would be more helpful than a contrived example. I hope this helps someone.