TransWikia.com

Mocking Firebase auth signInWithPopUp with jest for React App

Stack Overflow Asked by user881667 on December 5, 2021

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.

My login handler in App.js

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 = () => {
 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
    })
}

My mockFirebase.js

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) => {
    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(() => {
  jest.spyOn(firebaseSetup.firebaseAppAuth, 'signInWithPopup')
})

beforeEach(() => {
  firebaseSetup.firebaseAppAuth.signInWithPopup.mockImplementation(mockFirebase)
})

export default mockFirebase

my App.test.js

it('Firebase auth triggered when login clicked', async () => {
  render(<App/>)

  const result = fireEvent.click(screen.getByText(/Sign in with Google/i))
  expect(mockFirebase).toBeCalled()
  expect(result).toEqual(
    'result of signInWithPopup'
  )

})

My test is failing with the error:
Uncaught [TypeError: firebaseAppAuth.signInWithPopup(…).then is not a function]

If I remove the .then block the test fails on expect(result).toEqual(‘result of signInWithPopup’) with the error:

Expected: "result of signInWithPopup"
Received: true

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.

iotype’s suggestion plus changing my test structure to the following solved this issue.

it('Firebase auth triggerd when login clicked', async () => {
    fireEvent.click(screen.getByText(/Sign in with Google/i))
    await waitForElementToBeRemoved(() => screen.getByText(/Sign In With Google/i))
    expect(screen.getByText(/Welcome to Writual/i)).toBeInTheDocument()
    
  })
})

One Answer

I guess the issue is that signInWithPopup is a Promise which provides a then method. Therefor the mock must return a Promise with the same signature.

Answered by lotype on December 5, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP