# #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:
Решил эту проблему, издеваясь над ней вот так:
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)