能否在react-oidc-context中实现AuthState接口用于Next.js测试?
解决Vitest测试react-oidc-context时的
isAuthenticated未定义问题 完全可行,核心思路是mock react-oidc-context 提供的useAuth钩子(即你的自定义useOidcAuth),让它返回符合AuthContextProps类型的模拟对象,以此模拟已登录状态。以下是两种具体实现方法:
方法一:直接mock钩子(推荐)
在测试文件中,用Vitest的vi.mock替换目标钩子的导出,直接返回预设的已登录状态对象:
// index.test.jsx import { render, screen } from '@testing-library/react'; import Home from '../pages/index'; import { useAuth } from 'react-oidc-context'; // mock react-oidc-context的useAuth钩子 vi.mock('react-oidc-context', () => ({ useAuth: () => ({ isAuthenticated: true, // 按需补充组件用到的其他属性 user: { name: '测试用户', email: 'test@example.com' }, login: vi.fn(), logout: vi.fn() }) })); describe('首页', () => { it('已登录状态下渲染对应内容', () => { render(<Home />); // 断言已登录状态的渲染结果,比如是否显示用户欢迎语 expect(screen.getByText('欢迎回来')).toBeInTheDocument(); }); });
如果useOidcAuth是你自己封装的自定义钩子,直接mock该钩子即可:
// 假设useOidcAuth来自@/hooks/useOidcAuth vi.mock('@/hooks/useOidcAuth', () => ({ default: () => ({ isAuthenticated: true, user: { name: '测试用户' }, // 补充其他需要的属性 }) }));
方法二:用模拟Provider灵活切换状态
如果需要同时测试已登录/未登录等多场景,可以创建一个模拟的AuthProvider包裹测试组件:
import { render, screen } from '@testing-library/react'; import Home from '../pages/index'; import { AuthContext } from 'react-oidc-context'; // 定义模拟的AuthProvider组件 const MockAuthProvider = ({ children, authState }) => { // 默认未登录状态 const defaultState = { isAuthenticated: false, user: null, login: vi.fn(), logout: vi.fn() }; // 合并传入的自定义状态 const mergedAuthState = { ...defaultState, ...authState }; return ( <AuthContext.Provider value={mergedAuthState}> {children} </AuthContext.Provider> ); }; describe('首页', () => { it('已登录时显示用户信息', () => { render( <MockAuthProvider authState={{ isAuthenticated: true, user: { name: '测试用户' } }}> <Home /> </MockAuthProvider> ); expect(screen.getByText('用户信息')).toBeInTheDocument(); }); it('未登录时显示登录提示', () => { render( <MockAuthProvider authState={{ isAuthenticated: false }}> <Home /> </MockAuthProvider> ); expect(screen.getByText('请登录')).toBeInTheDocument(); }); });
关键注意事项
- 模拟对象需包含组件实际用到的所有
AuthContextProps属性,避免触发其他未定义错误; - 组件中用到的
login/logout等方法,可用vi.fn()模拟空函数,方便后续断言调用情况; - TypeScript项目中,可通过
Partial<AuthContextProps>约束模拟对象的类型,确保类型合规:import type { AuthContextProps } from 'react-oidc-context'; const mockAuth: Partial<AuthContextProps> = { isAuthenticated: true, user: { sub: 'test-user-id' } };
内容的提问来源于stack exchange,提问作者Brian
相关产品推荐
相关产品推荐

