使用Jest测试Next.js应用时Axios Node Adapter配置报错求助
问题描述
我正在尝试使用Jest测试我的Next.js应用,按照示例要求在测试模式下配置Axios使用Node Adapter,但出现了报错。以下是相关代码:
jest.setup.js
import '@testing-library/jest-dom/extend-expect' import axios from 'axios'; axios.defaults.adapter = require('axios/lib/adapters/http');
index.test.js
const mockedUseRoomsQuery = useRoomsQuery; jest.mock("../__mocks__/roomMockData.js"); const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, }, }, }); const wrapper = ({ children }) => ( <QueryClientProvider client={queryClient}> {children} </QueryClientProvider> ); describe("Fetch all rooms", () => { it("fetches all rooms", async () => { nock("https://63b29d465901da0ab368e025.mockapi.io", { reqheaders: { "app-id": () => true }, }) .persist() .get("/api/v1/rooms") .reply(200, roomData); const { result, waitFor } = renderHook(() => useRoomsQuery(), { wrapper }); await waitFor(() => result.current.isSuccess); console.log("data returned", result.current); }, 10000); });
请问我哪里操作出错了?(附带错误截图)
错误分析与修正方案
1. Axios适配器配置的模块格式冲突
你在jest.setup.js中混用了ES模块(import)和CommonJS(require)导入方式,这可能在Next.js的测试环境中导致模块加载异常。
修正:
统一使用ES模块语法导入适配器:
import '@testing-library/jest-dom/extend-expect'; import axios from 'axios'; import httpAdapter from 'axios/lib/adapters/http'; axios.defaults.adapter = httpAdapter;
2. Jest Mock使用错误
当前代码中jest.mock("../__mocks__/roomMockData.js")的目标是数据文件,但你需要mock的是useRoomsQuery这个自定义hook(或它依赖的查询逻辑)。另外代码中未导入useRoomsQuery就直接赋值给mockedUseRoomsQuery,会导致未定义错误。
修正:
- 首先确保正确导入
useRoomsQuery,然后mock它所在的模块:
// 假设useRoomsQuery从../hooks/useRoomsQuery导出 import { useRoomsQuery } from '../hooks/useRoomsQuery'; jest.mock('../hooks/useRoomsQuery');
- 在
__mocks__/useRoomsQuery.js中编写mock逻辑(如果需要模拟hook返回):
export const useRoomsQuery = jest.fn(() => ({ isSuccess: true, data: [] // 替换为测试所需的模拟数据 }));
3. Nock拦截配置问题
你的nock配置中reqheaders: { "app-id": () => true }的匹配逻辑可能过于严格,或者Axios请求实际并未携带该请求头,导致拦截失败,请求实际发送到真实接口从而报错。另外persist()在单次测试中没有必要。
修正:
调整请求头匹配逻辑,确保和Axios实际发送的请求头一致:
nock("https://63b29d465901da0ab368e025.mockapi.io") .matchHeader("app-id", /.*/) // 宽松匹配任意app-id值 .get("/api/v1/rooms") .reply(200, roomData);
同时确保roomData已经在测试文件中导入:
import { roomData } from '../__mocks__/roomMockData.js';
4. WaitFor断言缺失
当前waitFor(() => result.current.isSuccess)没有明确的断言,建议添加expect语句让测试更健壮:
await waitFor(() => expect(result.current.isSuccess).toBe(true), { timeout: 10000 });
内容的提问来源于stack exchange,提问作者Mo1
相关产品推荐
相关产品推荐

