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

React新手求助:编写使用useAuthContext的Jest测试时渲染报错

解决React中useAuthContext的Jest测试报错问题

问题说明

我不熟悉React,但需要编写使用useAuthContext的Jest单元测试,该Hook在同事开发的模块中被广泛使用。每次尝试渲染使用useAuthContext.js的组件时都会报错,错误提示为useAuthContext must be used inside an AuthContextProvider。我想了解如何传递该上下文,或是如何编写对应的渲染测试,尝试过多种方案但效果都不理想,恳请提供帮助!

相关代码

App.test.js

import React from "react";
import { render, screen } from "@testing-library/react";
import App from "./App";
import ReactDOM from 'react-dom';
import ShallowRenderer from 'react-shallow-renderer';

let realUseContext;
let useContextMock;
// Setup mock
beforeEach(() => {
    realUseContext = React.useContext;
    useContextMock = React.useContext = jest.fn();
});
// Cleanup mock
afterEach(() => {
    React.useContext = realUseContext;
});

test("mock hook", () => {
    const element = new ShallowRenderer().render(
        <App />
    );
});

test("render without failure", () => {
    const div = document.createElement("div");
    ReactDOM.render(<App />, div);
});

test("renders the nav bar", () => {
    render(<App />);
    const navbar = screen.getByTestId("navbar");
    expect(navbar).toBeInTheDocument();
});

App.js

import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'
import { useAuthContext } from './hooks/useAuthContext'

// pages & components
import Home from './pages/Home'
import Login from './pages/Login'
import Signup from './pages/Signup'
import LostPassword from './pages/LostPassword'
import WaitTimes from './pages/WaitTimes'
import Navbar from './components/Navbar'

function App() {
  const { user } = useAuthContext()

  return (
    
    <div className="App">
      <BrowserRouter>
        <Navbar />
        <div className="pages">
          <Routes>
            <Route 
              path="/" 
              element={user ? <Home /> : <Navigate to="/login" />} 
            />
            
            <Route 
              path="/login" 
              element={!user ? <Login /> : <Navigate to="/" />} 
            />
            <Route 
              path="/signup" 
              element={!user ? <Signup /> : <Navigate to="/" />} 
            />
            <Route 
              path="/lost" 
              element={!user ? <LostPassword /> : <Navigate to="/" />} 
            />
            
            <Route 
              path="/wait" 
              element={!user ? <WaitTimes /> : <Navigate to="/" />} 
            />
          </Routes>
        </div>
      </BrowserRouter>
    </div>
  );
}

export default App;

useAuthContext.js

import { AuthContext } from "../context/AuthContext"
import { useContext } from "react"

export const useAuthContext = () => {
  const context = useContext(AuthContext)

  if(!context) {
    throw Error('useAuthContext must be used inside an AuthContextProvider')
  }

  return context
}

解决方案

方法1:使用真实的AuthContextProvider包裹测试组件

直接在测试中导入项目中的AuthContextProvider,将被测试组件包裹起来,并传入模拟的上下文值:

// 导入AuthContextProvider(根据项目实际路径调整)
import { AuthContextProvider } from './context/AuthContext';

test("renders the nav bar", () => {
  render(
    <AuthContextProvider value={{ user: null }}> {/* 可根据测试需求传入null或模拟用户对象 */}
      <App />
    </AuthContextProvider>
  );
  const navbar = screen.getByTestId("navbar");
  expect(navbar).toBeInTheDocument();
});

这种方式最贴近真实运行环境,能覆盖不同用户状态下的路由跳转等场景。

方法2:Mock useAuthContext钩子

直接mock自定义的useAuthContext钩子,让它返回预设的上下文值:

// 在测试文件顶部mock钩子
jest.mock('./hooks/useAuthContext', () => ({
  useAuthContext: () => ({
    user: null, // 可根据测试场景改为{ id: '1', name: 'test' }等
  })
}));

test("renders the nav bar", () => {
  render(<App />);
  const navbar = screen.getByTestId("navbar");
  expect(navbar).toBeInTheDocument();
});

// 测试用户已登录时的路由跳转
test("redirects to home when user is logged in", () => {
  jest.mock('./hooks/useAuthContext', () => ({
    useAuthContext: () => ({
      user: { id: '1' },
    })
  }));
  render(<App />);
  // 根据Home组件的特征元素验证跳转结果
  expect(screen.getByText('Home')).toBeInTheDocument();
});

方法3:Mock React.useContext(适配现有代码思路)

如果你想沿用现有mock React.useContext的逻辑,需要让mock返回符合AuthContext要求的值,避免抛出错误:

import { AuthContext } from './context/AuthContext'; // 导入AuthContext

beforeEach(() => {
  realUseContext = React.useContext;
  // 针对AuthContext返回模拟值,其他上下文调用保留原有逻辑
  useContextMock = React.useContext = jest.fn((context) => {
    if (context === AuthContext) {
      return { user: null };
    }
    return realUseContext(context);
  });
});

test("renders the nav bar", () => {
  render(<App />);
  const navbar = screen.getByTestId("navbar");
  expect(navbar).toBeInTheDocument();
});

这种方式需要处理所有上下文调用场景,容易遗漏,因此更推荐前两种方案。


内容的提问来源于stack exchange,提问作者Zhe Wang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 20:31:08