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

如何测试自定义Hook返回布尔值的React条件渲染场景?

问题描述

我想测试Sidebar组件的条件渲染,但没法获取自定义Hook里的userHasAccess函数并让它返回true,导致测试用例里的Users元素没法渲染出来。相关代码如下:

useData.tsx

import React from 'react';

const useData = () => {

  function userHasAccess(access: 'student' | 'teacher' | 'admin'): boolean {
    return getLoggedUser()?.access === access
  }

  // 其他函数...

  return {
    userHasAccess,
    // 其他返回的函数...
  }
}

export default useData;
const Sidebar = () => {
  const { userHasAccess } = useData();

  return (
    <nav>
      <ul>
        {userHasAccess('admin') && <li><Link to='usuarios'>Users</Link></li>}
      </ul>
    </nav>
  )
}

export default Sidebar;
it('should render correctly for admin', () => {
  render(<BrowserRouter><Sidebar /></BrowserRouter>)

  expect(screen.getByText("Users")).toBeInTheDocument();
})

怎么修改才能让这个测试用例通过?


解决方案

有两种常用的实现方式:

方法一:直接模拟自定义Hook useData

用Jest的jest.mock方法模拟整个useData Hook,让它返回的userHasAccess函数固定返回true:

修改后的测试代码:

import { render, screen } from '@testing-library/react';
import { BrowserRouter } from 'react-router-dom';
import Sidebar from './Sidebar';
import useData from './useData';

// 模拟useData Hook
jest.mock('./useData');

it('should render correctly for admin', () => {
  // 让mock的useData返回自定义的userHasAccess,调用时始终返回true
  (useData as jest.Mock).mockReturnValue({
    userHasAccess: () => true,
    // 若组件用到Hook里的其他函数,需在这里同步模拟返回
  });

  render(<BrowserRouter><Sidebar /></BrowserRouter>);

  expect(screen.getByText("Users")).toBeInTheDocument();
});

方法二:模拟getLoggedUser函数

如果getLoggedUser是独立导出的函数,可以直接模拟它的返回值,让它返回拥有admin权限的用户对象,这样userHasAccess自然会返回true:

假设getLoggedUser从auth.ts模块导出,测试代码如下:

import { render, screen } from '@testing-library/react';
import { BrowserRouter } from 'react-router-dom';
import Sidebar from './Sidebar';
import { getLoggedUser } from './auth';

// 模拟getLoggedUser函数
jest.mock('./auth');

it('should render correctly for admin', () => {
  // 让getLoggedUser返回admin用户
  (getLoggedUser as jest.Mock).mockReturnValue({ access: 'admin' });

  render(<BrowserRouter><Sidebar /></BrowserRouter>);

  expect(screen.getByText("Users")).toBeInTheDocument();
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 15:52:36