Jest测试AppLayout时如何设置isAuthenticated为true避免解构报错
报错根因
现有测试代码仅在测试作用域内声明了同名的jest.fn()变量,没有和组件实际引入的useAuth、useApiService做绑定,且jest mock函数默认返回值为undefined。组件执行const { isAuthenticated } = useAuth()时,相当于对undefined做对象解构,直接抛出类型错误。
另外你当前测试里把isAuthenticated直接赋值为布尔值true也不符合实际实现——这个字段是返回布尔值的函数,如果直接传布尔值,后续执行isAuthenticated()时还会触发「isAuthenticated is not a function」的二次报错。
正确Mock配置步骤
- 用
jest.mock关联两个hook的实际引入路径,替换模块内的真实实现,不要写孤立的同名mock变量 - 给mock的hook配置返回值,覆盖组件内需要解构的所有字段:
useAuth返回带isAuthenticated方法的对象,useApiService返回带sendRequest方法的对象 - 每个测试用例执行前重置mock状态,避免不同用例的mock调用记录、返回值互相污染
修正后的测试代码示例
注意把代码里的hook引入路径替换成你项目的实际路径:
// mock对应模块,路径替换为项目内实际引入路径 jest.mock('@/hooks/useAuth', () => ({ useAuth: jest.fn() })); jest.mock('@/services/api-service', () => ({ useApiService: jest.fn() })); import { render } from '@testing-library/react'; import { useAuth } from '@/hooks/useAuth'; import { useApiService } from '@/services/api-service'; import AppLayout from './AppLayout'; describe('App General component', () => { const mockIsAuthenticated = jest.fn(); const mockSendRequest = jest.fn(); beforeEach(() => { // 每个用例执行前清空mock状态,设置默认返回 jest.clearAllMocks(); (useAuth as jest.Mock).mockReturnValue({ isAuthenticated: mockIsAuthenticated }); (useApiService as jest.Mock).mockReturnValue({ sendRequest: mockSendRequest }); }); const renderComponent = () => render(<AppLayout />); it('登录态下渲染无报错,会触发初始化数据拉取', () => { // 单独控制当前用例的登录态返回 mockIsAuthenticated.mockReturnValue(true); renderComponent(); // 可按需加断言验证逻辑 expect(mockIsAuthenticated).toHaveBeenCalledTimes(1); }); it('未登录态下渲染无报错,不会触发初始化数据拉取', () => { mockIsAuthenticated.mockReturnValue(false); renderComponent(); expect(mockIsAuthenticated).toHaveBeenCalledTimes(1); }); });
额外说明
如果需要测试不同登录态下的组件逻辑,只需要在对应测试用例里修改mockIsAuthenticated.mockReturnValue()的入参即可,不需要重复编写基础mock逻辑。
内容的提问来源于stack exchange,提问作者mrks
相关产品推荐
相关产品推荐

