如何用React Testing Library测试点击后链接消失场景
问题分析与解决方案
你的问题核心在于:测试点击"Show More Replies"链接后,链接未按预期消失,同时出现response.data未定义的错误。原因主要有两点:
- 测试中使用的
setComments是空jest mock函数,点击后组件接收的commentprops并未实际更新,导致组件重新渲染时仍显示链接。 - 若axios mock未正确配置,会导致异步请求返回
undefined,触发读取data属性的错误。
解决步骤
- 模拟真实状态更新:用React的
useState模拟父组件的状态管理,确保setComments能实际更新组件的comment数据。 - 提前配置axios mock:在渲染组件前设置好mock响应,避免异步请求返回
undefined。 - 验证链接消失:使用
waitForElementToBeRemoved等待组件重新渲染后,确认链接已被移除。
修改后的测试代码
/** * @jest-environment jsdom */ import "@testing-library/jest-dom"; import { render, screen, waitForElementToBeRemoved } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { useState } from "react"; import CommentThread from "../components/CommentThread"; jest.mock("axios"); const initialComment = { id: "4b2d74e6-7d1a-4ba3-9e95-0f52ee8ebc6e", author: "Reed Fisher", body: "Sint in in sunt amet.", postedAt: 1550488214207, replies_count: 3, replies: [ { id: "116dbd01-d5f3-4dfb-afeb-f822a9264a5e", comment_id: "4b2d74e6-7d1a-4ba3-9e95-0f52ee8ebc6e", author: "Kathleen Nikolaus", body: "Officia suscipit sint sint impedit nemo. Labore aut et quia quasi ut. Eos voluptatibus quidem eius delectus beatae excepturi.", postedAt: 1550419941546, }, ], }; const initialComments = [initialComment]; test("link disappears after clicking Show More Replies", async () => { const user = userEvent.setup(); // 模拟父组件的状态管理逻辑 const TestWrapper = () => { const [comments, setComments] = useState(initialComments); const currentComment = comments.find(c => c.id === initialComment.id); return ( <CommentThread comment={currentComment} comments={comments} setComments={setComments} /> ); }; // 配置axios mock响应 const mockReplies = [ { id: "116dbd01-d5f3-4dfb-afeb-f822a9264a5f", comment_id: "4b2d74e6-7d1a-4ba3-9e95-0f52ee8ebc6e", author: "Srdjan", body: "Officia suscipit sint sint impedit nemo. Labore aut et quia quasi ut. Eos voluptatibus quidem eius delectus beatae excepturi.", postedAt: 1550419941546, }, { id: "116dbd01-d5f3-4dfb-afeb-f822a9264a5d", comment_id: "4b2d74e6-7d1a-4ba3-9e95-0f52ee8ebc6e", author: "Max", body: "Officia suscipit sint sint impedit nemo. Labore aut et quia quasi ut. Eos voluptatibus quidem eius delectus beatae excepturi.", postedAt: 1550419941546, }, ]; axios.get.mockResolvedValueOnce({ data: mockReplies }); render(<TestWrapper />); // 获取并点击链接 const showMoreLink = screen.getByRole("link", { name: /Show More Replies/ }); await user.click(showMoreLink); // 验证请求地址正确 expect(axios.get).toHaveBeenCalledWith( `/api/comment_replies?comment_id=${initialComment.id}` ); // 等待链接被移除 await waitForElementToBeRemoved(showMoreLink); // 最终验证链接不存在 expect(screen.queryByRole("link", { name: /Show More Replies/ })).not.toBeInTheDocument(); });
关键修改说明
- TestWrapper组件:通过
useState模拟真实父组件的状态更新,确保点击后comment.replies长度变为3,与replies_count相等,从而隐藏链接。 - 提前配置mock:在渲染前设置axios响应,避免异步请求返回
undefined。 - waitForElementToBeRemoved:等待组件完成重新渲染和状态更新后,再断言链接已消失。
内容的提问来源于stack exchange,提问作者SrdjaNo1
相关产品推荐
相关产品推荐

