Получить ошибку Firebase: Приложение Firebase «[ПО УМОЛЧАНИЮ] » не было создано при использовании библиотеки React-hooks-тестирования с шуткой

# #reactjs #firebase #jestjs #react-testing-library #react-hooks-testing-library

Вопрос:

Я использую Firebase auth в React и пытаюсь протестировать его с react-hooks-testing-library помощью . Код, который я пишу, работает. Но когда я пытаюсь протестировать с react-hooks-testing-library помощью, я получаю эту ошибку:

Ошибка FirebaseError: Firebase: Приложение Firebase «[ПО УМОЛЧАНИЮ] » не создано , вызовите приложение Firebase.initializeApp() (приложение/без приложения).

Вот мой фактический код:

useAuth.tsx

 const defaultValue = {
     .. some value here
}

const AuthContext = createContext(defaultValue)

const AuthContextProvider = (props) => {
    const auth = useFirebaseAuth()

    return (
        <AuthContext.Provider
            value={auth}
        >
            {props.children}
        </AuthContext.Provider>
    );
}

const useAuth = () => {
    return useContext(AuthContext)
}

// I will like to test the function and behaviour inside this hooks, useFirebaseAuth() here
export default function useFirebaseAuth() {

    const [user, setUser] = useState(null)

  
    const loginWithEmailPassword = (email: string, password: string) => {

        const auth = getAuth() // the error point to this line!!! 

        //this code I followed the Firebase docs    
        return signInWithEmailAndPassword(auth, email, password)
            .then(res => {

            }).catch(error => {

            })
    }

    const signUpWithEmailPassword = () => {

    }


    return {
        user,
        loginWithEmailPassword,
        signUpWithEmailPassword
    }

}

export { useAuth, AuthContextProvider }
 

Внутри этого крючка будет 3 предмета, которые user , loginWithEmailPassword , signUpWithEmailPassword

Вот мой тест

useAuth.test.tsx

 import React from 'react'
import { renderHook, act } from '@testing-library/react-hooks/native'
import useFirebaseAuth from '../useAuth';

// Here I tried to mock the auth function of Firebase
jest.mock('firebase/app', () => {
    return {
        App: () => ({
            app: mockGetApp
        }),
        auth: () => ({
            signInWithEmailAndPassword: mockSignIn,
            createUserWithEmailAndPassword: mockSignUp
        })
    }
})

const mockInitializeFirebase = jest.fn()
const mockSignUp = jest.fn(() => Promise.resolve())
const mockSignIn = jest.fn(() => Promise.resolve())
const mockGetApp = jest.fn()

jest.mock('../../utils/initAuth', () => {
    return {
        app: mockInitializeFirebase
    }
})

describe('useAuth Hooks testing', () => {

    test('Login with Email and Password', () => {
        const { result } = renderHook(() => useFirebaseAuth())

        console.log(result)

        //arrange it, confirm the initial state 
        expect(result.current.user).toBe(null)
        expect(typeof result.current.loginWithEmailPassword).toBe('function')
        expect(typeof result.current.signUpWithEmailPassword).toBe('function')

        const email = 'abc@gmail.com'
        const password = '123456'
        // here act
        act(() => {
            // The problem come from this line
            result.current.loginWithEmailPassword(email, password)
        })
        // here assert 
        expect(mockSignIn).toBeCalledWith(email, password)

    })
})
 

Поэтому, когда я запустил loginWithEmailPassword(email,password) функцию, она продолжала отображаться No Firebase App error . Но в моем проекте у меня уже есть этот файл, который уже инициализирует приложение Firebase.

./initFirebase.tsx, здесь уже инициализируйте приложение и вызовите его в index.tsx

 import { initializeApp, getApps, getApp } from "firebase/app";
import getEnvVars from '../environment'

const env = getEnvVars()

interface firebaseType {
    apiKey: string,
    authDomain: string,
    projectId: string,
    messagingSenderId: string
}

let firebaseConfig: firebaseType;

if (env !== null) {

    const { apiKey, authDomain, projectId, messagingSenderId } = env
    firebaseConfig = {
        apiKey: apiKey,
        authDomain: authDomain,
        projectId: projectId,
        messagingSenderId: messagingSenderId
    };
}

export const initFirebase = () => {
    if (getApps().length === 0) {
        initializeApp(firebaseConfig);
    } else {
        getApp()
    }
}
 

Таким образом, ошибка произошла только в тесте, поэтому я думаю, что мне следует поиздеваться над initializeApp функцией и вызвать ее где-нибудь в тесте. Но я не знаю, как это сделать.

Я только начинаю работать в testing полевых условиях. Кто-нибудь, у кого есть опыт, пожалуйста, помогите.

Вот в чем вопрос:

  1. Что случилось с моим кодом и тестом, из-за которых произошла ошибка?
  2. Что я должен сделать, чтобы устранить эту ошибку?

Заранее спасибо.

Ответ №1:

Решил эту проблему, издеваясь над ней вот так:

 const mockSignUp = jest.fn(() => {
    return Promise.resolve({
        user: {
            uid: "fakeuid",
        },
    });
})
const mockSignIn = jest.fn(() => Promise.resolve({
    user: {
        uid: "fakeUid"
    }
}))

const mockGetAuth = jest.fn()

jest.mock('firebase/auth', () => {
    return {
        getAuth: () => mockGetAuth,
        signInWithEmailAndPassword: () => mockSignIn,
        createUserWithEmailAndPassword: () => mockSignUp
    }
})
 

Отмечено этим:

getAuth: ()=> mockGetAuth функция 3 там, это будет имитировать, как getAuth() в firebase, функцию mockGetAuth, которую я определил.

Затем в тесте я могу вызвать функцию макета следующим образом:

 // here check the mock function 
mockSignIn(mockGetAuth, email, password)
expect(mockSignIn).toBeCalledWith(mockGetAuth, email, password)