如何用React Testing Library测试useState驱动的组件渲染
修正后的SettingsContainer测试用例
先明确原测试代码存在的核心问题:
- 对象字面量语法错误:
const respData = { show_abe = true, show_def = true };需将等号=改为冒号: - Mock返回结构错误:原mock把数据嵌套在
respData字段下,但组件期望resp.data直接包含show_abe和show_def - 未重置Mock函数:测试间未清理mock状态,易导致干扰
- 子组件缺少测试标识:原组件的
<abc>和<def>无data-testid,无法通过getByTestId查询
修正后的测试代码
const respData = { show_abe: true, show_def: true }; // 正确mock API,直接返回目标数据结构 jest.mock('../../hooks/apis', () => ({ getSettings: jest.fn(() => Promise.resolve({ data: respData })), })); describe('SettingsContainer', () => { beforeEach(() => { // 每次测试前重置mock,避免测试间状态污染 jest.clearAllMocks(); render(<HashRouter><SettingsContainer /></HashRouter>); }); // 注:原组件无"Settings"标题,若需保留此测试需先在组件中添加对应元素 test('显示页面标题', () => { expect(screen.getByText('Settings')).toBeInTheDocument(); }); test('API返回开关为true时,正确渲染abc和def组件', async () => { // 使用findBy*内置异步等待机制,替代waitFor包裹getBy* const abcComponent = await screen.findByTestId('abc'); const defComponent = await screen.findByTestId('def'); expect(abcComponent).toBeInTheDocument(); expect(abcComponent).toHaveTextContent('ABC'); expect(defComponent).toBeInTheDocument(); expect(defComponent).toHaveTextContent('DEF'); }); // 补充测试:开关为false时不渲染对应组件 test('API返回show_abe为false时,不渲染abc组件', async () => { // 重新mock返回数据 require('../../hooks/apis').getSettings.mockResolvedValue({ data: { show_abe: false, show_def: true } }); render(<HashRouter><SettingsContainer /></HashRouter>); // 查询不存在的元素需用queryBy*,并判断不存在 const abcComponent = screen.queryByTestId('abc'); expect(abcComponent).not.toBeInTheDocument(); const defComponent = await screen.findByTestId('def'); expect(defComponent).toBeInTheDocument(); }); });
配套修改原组件(添加测试标识)
return ( <div> {show_abe ? <abc data-testid="abc"></abc> : null } {show_def ? <def data-testid="def"></def> : null } </div> )
内容的提问来源于stack exchange,提问作者pareshm
相关产品推荐
相关产品推荐

