You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 15:52:18