How do you mock Firebase Firestore methods using Jest?

前端 未结 7 1779
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-17 17:12

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.

7条回答
  •  感动是毒
    2020-12-17 18:00

    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 => (
              
    {props.errors.email && (

    {props.errors.email}

    )}
    )} /> ); }; 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.

提交回复
热议问题