如何测试React组件中遍历生成的每个按钮点击后是否禁用
问题解决
报错原因
screen.getAllByRole('button')返回的是所有匹配按钮的 HTMLElement数组,而fireEvent.click仅支持传入单个DOM元素,因此触发类型不匹配报错。
不需要为每个按钮单独编写测试用例
你可以通过遍历按钮数组的方式批量验证所有按钮的点击禁用逻辑,示例代码如下:
// 先模拟组件所需的相关参数 const mockSortVariant = { payType: 'online' }; // 替换为你实际的sortVariant取值 const sortDirections = ['asc', 'desc', 'priceAsc', 'priceDesc']; // 替换为你实际的排序方向列表 const mockHandleSortFilters = jest.fn(); it('所有排序按钮点击后应进入禁用状态', () => { // 初始化排序筛选参数 let testSortFilters = { direction: '', payType: '' }; const { rerender } = render( <ProductSorter sortFilters={testSortFilters} handleSortFilters={mockHandleSortFilters} sortVariant={mockSortVariant} // 注意你原测试代码漏传了这个props,需要补上 /> ); const buttons = screen.getAllByRole('button'); expect(buttons).toHaveLength(4); // 遍历所有按钮逐个验证逻辑 buttons.forEach((button, index) => { const expectedDirection = sortDirections[index]; // 点击当前按钮 fireEvent.click(button); // 验证回调函数接收到的参数正确 expect(mockHandleSortFilters).toHaveBeenCalledWith({ payType: mockSortVariant.payType, direction: expectedDirection }); // 更新排序筛选参数后重渲染组件,模拟父组件状态更新的逻辑 testSortFilters = { payType: mockSortVariant.payType, direction: expectedDirection }; rerender( <ProductSorter sortFilters={testSortFilters} handleSortFilters={mockHandleSortFilters} sortVariant={mockSortVariant} /> ); // 验证当前按钮已禁用,其他按钮未禁用 expect(button).toBeDisabled(); buttons.forEach((otherBtn, otherIndex) => { if (otherIndex !== index) expect(otherBtn).not.toBeDisabled(); }); // 重置mock调用记录,避免影响下一轮循环校验 mockHandleSortFilters.mockClear(); }); });
注意事项
如果你的组件是内部维护sortFilters状态的非受控组件,不需要手动调用rerender,点击按钮后直接等待状态更新完成后验证禁用状态即可。
内容的提问来源于stack exchange,提问作者DGB
相关产品推荐
相关产品推荐

