我需要帮助解决在用于检索用户数据的钩子上运行单元测试时出现的错误。
TypeError: _app.default.auth is not a function 10 | setUserId(storedUserId); 11 | } else { > 12 | const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
仅在为我创建的用于从存储或 Firebase 检索用户信息的钩子运行单元测试时,才会出现上述错误。如果 storage === null,则此钩子会先查找存储,然后查找 Firebase。
import { useEffect, useState } from "react";
import useGetUserId from "./useGetUserId";
import { app } from "../environments/environment";
import { doc, getDoc, getFirestore } from "firebase/firestore";
const useGetUserProfile = () => {
type profile = {
email: string;
username: string;
userBio: string;
dob: Date;
gender: string;
sexo: string;
education: string;
drinkingHabits: string;
smokingHabits: string;
};
const db = getFirestore(app);
const userId: string | null = useGetUserId();
const [isLoading, setIsLoading] = useState(true);
const [userProfile, setUserProfile] = useState<any | null>(null);
useEffect(() => {
const userProfile = async () => {
setIsLoading(true);
try {
const userRef = localStorage.getItem("PROFILE_INFO");
if (userRef) {
const profile: profile = JSON.parse(userRef);
setUserProfile(profile);
} else {
if (userId) {
const id = JSON.parse(userId);
const userRef = await getDoc(doc(db, "users", id.user.uid));
if (userRef.exists()) {
const profile = userRef.data();
setUserProfile(profile);
}
}
}
} catch (error) {
console.log("error", error);
} finally {
setIsLoading(false);
}
};
userProfile();
}, [setUserProfile]);
return {
isLoading,
userProfile, setUserProfile
};
};
export default useGetUserProfile;
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
export const firebaseConfig = {
//config properties
};
// Initialize Firebase
export const app = initializeApp(firebaseConfig);
// Initialize Firebase Authentication and get a reference to the service
export const auth = getAuth(app);
以及单元测试:
// Mocking Firebase Firestore methods
jest.mock('firebase/firestore', () => ({
getFirestore: jest.fn(),
doc: jest.fn(),
getDoc: jest.fn(),
}));
// Mocking localStorage
beforeEach(() => {
jest.spyOn(Storage.prototype, 'getItem').mockImplementation(() => null); // Reset localStorage
});
describe('useGetUserProfile', () => {
it.only('should get user profile from localStorage if available', async () => {
// Mock localStorage with a mock profile
const mockProfile = {
email: '[email protected]',
username: 'testuser',
userBio: 'Bio info',
dob: new Date('1990-01-01'),
gender: 'Male',
sexo: 'M',
education: 'Bachelor',
drinkingHabits: 'Occasionally',
smokingHabits: 'Non-smoker',
};
jest.spyOn(Storage.prototype, 'getItem').mockImplementationOnce(() => JSON.stringify(mockProfile));
const { result } = renderHook(() => useGetUserProfile());
expect(result.current.userProfile).toEqual(mockProfile);
});
我只在运行单元测试时收到错误,我想我设置 Firebase 配置的方式一定存在错误,但我不确定。
实际的错误是它显示在一个获取 UserId 的单独钩子中,但是该钩子的单元测试并没有失败。
这是在单独的 Hook 的单元测试中导致错误的实际代码行。
useEffect(() => {
const storedUserId = localStorage.getItem("USER_CREDENTIALS");
if (storedUserId) {
setUserId(storedUserId);
} else {
const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
if (user) {
const uid = user.uid;
localStorage.setItem("USER_CREDENTIALS", uid);
setUserId(uid);
}
});
return () => unsubscribe();
}
}, [userId]);
return userId;
};
根据您提供的代码,只要本地存储包含的条目
"USER_CREDENTIALS"
,就会完全跳过引发错误的逻辑。当你模拟
localStorage.getItem()
总是返回时null
,你现在会导致错误的逻辑执行。要将此旧逻辑更新为新语法,您可以使用以下命令: