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