Get Firebase Error: No Firebase App '[DEFAULT]' has been created when using React-hooks-testing-library with jest
Get Firebase Error: No Firebase App '[DEFAULT]' has been created when using React-hooks-testing-library with jest
我在 React 中使用 Firebase 身份验证,并尝试使用 react-hooks-testing-library
对其进行测试。我写的代码正在运行。但是当我尝试使用 react-hooks-testing-library
进行测试时,我得到了这个错误:
FirebaseError: Firebase: No Firebase App '[DEFAULT]' has been created
, call Firebase App.initializeApp() (app/no-app).
这是我的实际代码:
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个item,分别是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,这里已经初始化了app,并在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
领域。请有经验的朋友帮忙一下
这里是问题:
我的代码和测试发生了什么导致错误发生?
我应该怎么做才能解决这个错误?
提前谢谢你。
通过像这样模拟它解决了这个问题:
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 函数,这将在 firebase 中模拟为我定义的 mockGetAuth 函数的 getAuth()
。
然后在测试中我可以这样调用模拟函数:
// here check the mock function
mockSignIn(mockGetAuth, email, password)
expect(mockSignIn).toBeCalledWith(mockGetAuth, email, password)
我在 React 中使用 Firebase 身份验证,并尝试使用 react-hooks-testing-library
对其进行测试。我写的代码正在运行。但是当我尝试使用 react-hooks-testing-library
进行测试时,我得到了这个错误:
FirebaseError: Firebase: No Firebase App '[DEFAULT]' has been created , call Firebase App.initializeApp() (app/no-app).
这是我的实际代码:
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个item,分别是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,这里已经初始化了app,并在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
领域。请有经验的朋友帮忙一下
这里是问题:
我的代码和测试发生了什么导致错误发生?
我应该怎么做才能解决这个错误?
提前谢谢你。
通过像这样模拟它解决了这个问题:
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 函数,这将在 firebase 中模拟为我定义的 mockGetAuth 函数的 getAuth()
。
然后在测试中我可以这样调用模拟函数:
// here check the mock function
mockSignIn(mockGetAuth, email, password)
expect(mockSignIn).toBeCalledWith(mockGetAuth, email, password)