title: Mocking Firebase auth signInWithPopUp with jest for React App
body: <p>I am having some issues testing my react apps sign in method. I am attempting to mock firebase auth's signInWithPopup method when I click the Sign in Button in my test.</p>
  <p>My login handler in App.js</p>
  <pre><code>import * as firebase from 'firebase/app';
  import 'firebase/auth';
  import firebaseSetup from './firebaseSetup'
      
  const firebaseApp = firebaseSetup.firebaseApp
  
  const firebaseAppAuth = firebaseSetup.firebaseAppAuth
  
  const providers = firebaseSetup.providers 
  
  handleGoogleLogin = () =&gt; {
   firebaseAppAuth.signInWithPopup(providers.googleProvider)
      .then(function(result) {
        this.setState({
          token: result.credential.accessToken,
          signedInUser: result.user
        })
      }).catch(function(error) {
        let errorCode = error.code
        let errorMessage = error.message
        let errorEmail = error.email
        let errorCredential = error.credential
      })
  }
  </code></pre>
  <p>My mockFirebase.js</p>
  <pre><code>import * as firebase from 'firebase/app'
  import firebaseConfig from './firebaseConfig';
  import 'firebase/auth'
  import App from './App'
  import firebaseSetup from './firebaseSetup'
  
  const mockFirebase = jest.fn( (functionName) =&gt; {
      console.log('mockFirebase', typeof functionName.providerId)
      switch(functionName.providerId) {
          case 'google.com': {
              console.log('google case')
              return 'result of signInWithPopup'
          }
  
          default: {
              throw new Error(`Unhandled firebase request: ${url}`)
          }
      }
  }) 
  
  beforeAll(() =&gt; {
    jest.spyOn(firebaseSetup.firebaseAppAuth, 'signInWithPopup')
  })
  
  beforeEach(() =&gt; {
    firebaseSetup.firebaseAppAuth.signInWithPopup.mockImplementation(mockFirebase)
  })
  
  export default mockFirebase
  </code></pre>
  <p>my App.test.js</p>
  <pre><code>it('Firebase auth triggered when login clicked', async () =&gt; {
    render(&lt;App/&gt;)
  
    const result = fireEvent.click(screen.getByText(/Sign in with Google/i))
    expect(mockFirebase).toBeCalled()
    expect(result).toEqual(
      'result of signInWithPopup'
    )
  
  })
  </code></pre>
  <p>My test is failing with the error:
  Uncaught [TypeError: firebaseAppAuth.signInWithPopup(...).then is not a function]</p>
  <p>If I remove the .then block the test fails on expect(result).toEqual('result of signInWithPopup') with the error:</p>
  <p>Expected: &quot;result of signInWithPopup&quot;
  Received: true</p>
  <p>I am not sure why the .then block is causing an error or why I cannot get the return result of the match switch case in the mockFirebase function in my result const when the test clicks the login button.</p>
  <p>iotype's suggestion plus changing my test structure to the following solved this issue.</p>
  <pre><code>it('Firebase auth triggerd when login clicked', async () =&gt; {
      fireEvent.click(screen.getByText(/Sign in with Google/i))
      await waitForElementToBeRemoved(() =&gt; screen.getByText(/Sign In With Google/i))
      expect(screen.getByText(/Welcome to Writual/i)).toBeInTheDocument()
      
    })
  })
  </code></pre>