如何用React Testing Library测试点击后显示的隐藏元素及函数调用?
React Testing Library 测试下拉菜单问题解决
问题描述
我实现了一个自定义下拉菜单,包含两个选项,点击下拉按钮后选项才会显示,点击选项会触发对应函数。使用React Testing Library测试时遇到问题:点击下拉按钮后无法检测到原本隐藏的选项,导致测试失败(之前未放入下拉菜单时测试正常)。需要完成两个测试目标:
- 点击下拉菜单后能检测到对应的选项元素;
- 点击显示后的选项,验证对应函数是否触发。
原测试代码
test('expect that await getXMLDownload is called when Download XML is clicked', async () => { setup(props); const button = screen.queryByTestId('download-button'); userEvent.click(button); await waitFor(() => { expect(screen.getByText('Download XML')).toBeInTheDocument(); // 测试失败,找不到元素 }); const downloadXML = screen.getByText('Download XML'); userEvent.click(downloadXML); expect(props.getXMLDownload).toHaveBeenCalled(); });
原组件代码
<DropdownMenu trigger={( <Button data-testid="download-button" variant={ButtonVariant.secondary} style={{ textTransform: 'none' }} > <Icon size="large" icon={IconName.Download} /> </Button> )} > <DropdownMenu.Item> <p onClick={() => initiateTxtDownload( `activity_report_${new Date()}`, generateTxtReport(reportData, agent, fraudTypesData), )} > Download Text </p> </DropdownMenu.Item> <DropdownMenu.Item> {sarReportV2 && ( <p onClick={async () => initiateTxtDownload( `activity_report_${new Date()}${caseToken}.xml`, (await getXMLDownload(domainToken)).payload, )} >Download XML </p> )} </DropdownMenu.Item> </DropdownMenu>
解决方案
1. 修正异步元素检测逻辑
React Testing Library的findByText是异步查询方法,会自动等待元素出现,比waitFor+getByText更简洁可靠。替换原有的等待逻辑,直接用await screen.findByText获取下拉选项。
2. 确保条件渲染元素正常渲染
"Download XML"选项依赖sarReportV2变量渲染,测试时必须在props中传入sarReportV2: true,否则该元素不会被渲染,测试必然失败。
3. Mock异步函数避免真实请求
getXMLDownload是异步函数,测试时用jest.fn().mockResolvedValue模拟返回值,避免真实异步操作干扰测试流程。
修改后的测试代码
test('点击Download XML时触发getXMLDownload', async () => { // 构造测试props,确保sarReportV2为true,mock异步函数 const testProps = { ...props, sarReportV2: true, getXMLDownload: jest.fn().mockResolvedValue({ payload: 'mock-xml-data' }) }; setup(testProps); // 点击下拉触发按钮 const downloadBtn = screen.getByTestId('download-button'); await userEvent.click(downloadBtn); // 等待并获取Download XML选项 const xmlOption = await screen.findByText('Download XML'); await userEvent.click(xmlOption); // 验证函数调用 expect(testProps.getXMLDownload).toHaveBeenCalled(); });
额外注意事项
- 确认
DropdownMenu组件点击后正确切换菜单可见状态,渲染的选项元素未被标记为aria-hidden="true"或display: none(组件库内部的隐藏逻辑React Testing Library会自动识别,但自定义组件需确保状态切换正确); - 如果是自定义下拉菜单,确保菜单元素在DOM中存在(仅样式隐藏),而非动态添加/移除DOM节点,否则查询逻辑需要调整。
内容的提问来源于stack exchange,提问作者London804
相关产品推荐
相关产品推荐

