React测试问题:点击按钮无法从DOM中移除元素
React测试点击删除按钮后元素未从DOM移除的问题修复
问题分析
你的测试存在两个核心问题导致元素未被移除:
waitForElementToBeRemoved使用错误
该函数的正确用法是传入要等待移除的元素或者返回该元素的查询函数,而不是传入一个expect断言。你当前传入的expect(queryByText('')).not.toBeInTheDocument()既没有指定目标元素(空字符串无法匹配),也不符合函数的参数要求。未模拟组件的状态更新逻辑
你的组件是受控组件,渲染的列表依赖于传入的itemsprops。点击删除按钮后,父组件需要更新items数组来移除对应项,组件才会重新渲染并移除DOM元素。但你测试中使用的onDelete: jest.fn()只是一个空模拟函数,没有触发items的更新,所以组件仍然渲染原始的列表项。
修复步骤
1. 修正 waitForElementToBeRemoved 的用法
将其改为传入查询目标元素的函数,比如查询"foo"元素的函数:
await waitForElementToBeRemoved(() => queryByText("foo"));
2. 模拟 onDelete 函数来更新 items
在测试中,当onDelete被调用时,需要更新测试用的items数组,并让组件重新接收新的props。可以使用rerender方法来重新渲染组件:
修改后的完整测试代码
const testProps = { items: [ { id: "0", label: "foo" }, { id: "1", label: "bar" } ], onDelete: jest.fn() }; test("delete item", async () => { const { findAllByRole, queryByText, rerender } = render(<Items {...testProps} />); expect(queryByText("foo")).toBeInTheDocument(); const deleteButton = await findAllByRole("button", { name: /remove/i }); userEvent.click(deleteButton[0]); expect(testProps.onDelete).toHaveBeenCalledTimes(1); // 获取被删除项的id(假设onDelete会传入id参数) const deletedId = testProps.onDelete.mock.calls[0][0]; // 更新items数组,移除被删除的项 const updatedItems = testProps.items.filter(item => item.id !== deletedId); // 重新渲染组件,传入更新后的items rerender(<Items {...testProps} items={updatedItems} />); // 等待元素被移除 await waitForElementToBeRemoved(() => queryByText("foo")); // 验证元素确实不在DOM中 expect(queryByText("foo")).not.toBeInTheDocument(); });
额外注意
你提供的HTML结构中onCLick拼写错误(应为onClick),虽然你说UI中正常,但建议修正这个拼写错误避免潜在问题。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

