React测试中如何等待按钮在fetch完成后移除disabled属性恢复可用
问题解决方法
你现有测试失败的原因是:点击按钮后断言执行的时机远早于所有fetch请求完成、isTesting状态设为false的时机,此时按钮还处于禁用状态,自然无法通过校验。
你可以使用React Testing Library内置的waitFor工具实现「等待指定条件成立」的需求,调整后的测试代码如下:
import { waitFor } from '@testing-library/react'; it("re-enables the test button after loading", async () => { getTest.mockRejectedValue("failed"); render(<CreateItem />); (await screen.findByText("Test")).click(); const testBtn = (await screen.findByText("Test")).closest("button"); if (!testBtn) throw new Error("could not find test button"); // 等待按钮不再被禁用,超时时间可根据需要调整,默认1000ms await waitFor(() => { expect(testBtn).not.toHaveAttribute("disabled"); }, { timeout: 2000 }); });
额外说明
- 你之前校验点击后按钮禁用的逻辑能成功,是因为
setIsTesting(true)是点击后同步执行的,状态更新速度快,刚好在你执行断言前完成;而setIsTesting(false)是在所有异步fetch请求完成后才执行,属于异步更新,必须等待才能拿到正确的状态。 - 如果需要等待元素具备某属性,只需要把断言改成
expect(testBtn).toHaveAttribute("disabled")即可,同样用waitFor包裹就行。 - 搭配
@testing-library/jest-dom的匹配器可以简化写法,更符合直觉:await waitFor(() => expect(testBtn).not.toBeDisabled());
内容的提问来源于stack exchange,提问作者Elias
相关产品推荐
相关产品推荐

