简体   繁体   English

Mocking Firebase auth signInWithPopUp with jest for React App

[英]Mocking Firebase auth signInWithPopUp with jest for React App

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.当我在测试中单击登录按钮时,我试图模拟 firebase auth 的 signInWithPopup 方法。

My login handler in App.js我在 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我的 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我的 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]我的测试因错误而失败:未捕获 [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:如果我删除 .then 块,测试在 expect(result).toEqual('result of signInWithPopup') 上失败,并出现错误:

Expected: "result of signInWithPopup" Received: true预期:“signInWithPopup 的结果” 接收:真

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.我不确定为什么 .then 块会导致错误,或者为什么当测试单击登录按钮时,我的结果 const 中的 mockFirebase function 中的 match switch case 无法返回结果。

iotype's suggestion plus changing my test structure to the following solved this issue. iotype 的建议加上将我的测试结构更改为以下解决了这个问题。

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

I guess the issue is that signInWithPopup is a Promise which provides a then method.我想问题是signInWithPopup是一个 Promise ,它提供了一个then方法。 Therefor the mock must return a Promise with the same signature.因此,模拟必须返回具有相同签名的 Promise。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM