如何测试自定义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;
Sidebar.tsx
const Sidebar = () => { const { userHasAccess } = useData(); return ( <nav> <ul> {userHasAccess('admin') && <li><Link to='usuarios'>Users</Link></li>} </ul> </nav> ) } export default Sidebar;
Sidebar.test.tsx
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
相关产品推荐
相关产品推荐

