Next.js项目中使用Axios编写React测试时出现TypeError问题求助
Next.js项目中使用Axios编写React测试时出现TypeError问题求助
我来帮你分析问题根源,以及对应的解决方法:
错误原因拆解
你遇到的TypeError: Cannot read properties of undefined (reading 'response')主要来自两个地方:
- 组件未接收必要Props:你的
Index组件依赖getServerSideProps传入的trendingprops,但测试中直接渲染<Index />时没有传递这个参数,导致trending是undefined,访问trending.response自然报错。 - Axios Mock结构不符:Axios的请求返回有固定结构——接口返回的数据会被包裹在
data字段里,但你当前的mock直接返回了{ response: [...] },和实际Axios响应的结构不匹配。
具体修复步骤
1. 修正Axios的Mock结构
实际场景中,你的API路由返回{ response: [...] },getServerSideProps里通过Axios请求后,拿到的response.data就是这个对象。所以Axios的mock需要包裹一层data字段,对应Axios的标准响应结构:
axios.get.mockResolvedValueOnce({ data: { // 必须包裹这层data response: [ { adult: false, backdrop_path: "/2Icjry0xdRSNxrtsBR1F47b9r3u.jpg", id: 615656, title: "Meg 2: The Trench", // 其他字段保持不变 }, ], }, });
2. 给Index组件传入Props(或模拟getServerSideProps执行)
测试环境中Next.js不会自动调用getServerSideProps,所以你需要手动构造trending props并传递给组件。修改后的完整测试代码如下:
import { render, screen } from "@testing-library/react"; import "@testing-library/jest-dom"; import axios from "axios"; import Index from "@/pages/index"; describe("Index components", () => { test("renders heading trending", async () => { // 修正Axios mock结构 axios.get = jest.fn(); axios.get.mockResolvedValueOnce({ data: { response: [ { adult: false, backdrop_path: "/2Icjry0xdRSNxrtsBR1F47b9r3u.jpg", id: 615656, title: "Meg 2: The Trench", original_language: "en", original_title: "Meg 2: The Trench", overview: "An exploratory dive into the deepest depths of the ocean of a daring research team spirals into chaos when a malevolent mining operation threatens their mission and forces them into a high-stakes battle for survival.", poster_path: "/4m1Au3YkjqsxF8iwQy0fPYSxE0h.jpg", media_type: "movie", genre_ids: [28, 878, 27], popularity: 8742.665, release_date: "2023-08-02", video: false, vote_average: 6.977, vote_count: 1062, }, ], }, }); // 手动构造props传递给Index组件 const mockProps = { trending: { response: [ { adult: false, id: 615656, title: "Meg 2: The Trench", // 字段可以和mock保持一致,也可以简化 }, ], }, }; render(<Index {...mockProps} />); const headingElement = screen.getByText("whats trending", { exact: false }); expect(headingElement).toBeInTheDocument(); }); });
额外优化方案(贴近真实场景)
如果你想更贴近真实业务逻辑,也可以直接调用getServerSideProps获取props后再渲染组件:
test("renders heading trending with getServerSideProps", async () => { axios.get.mockResolvedValueOnce({ data: { response: [...] } }); // 调用getServerSideProps获取props const propsResult = await Index.getServerSideProps({}); render(<Index {...propsResult.props} />); const headingElement = screen.getByText("whats trending", { exact: false }); expect(headingElement).toBeInTheDocument(); });
这样就能解决你遇到的TypeError问题啦!
备注:内容来源于stack exchange,提问作者Christoff Van Der Walt
相关产品推荐
相关产品推荐

