NodeJS TDD单元测试报错:expect(jest.fn()).toBeCalledWith(200)调用次数为0
问题原因与修复方案
你的测试失败核心原因是没有mock axios.get方法,运行测试时会真实发起HTTP请求到"some URL":要么请求失败进入catch分支调用next(error),要么返回的响应数据不符合interfaces.SuccessStruct结构(比如没有statusCode字段或值不是200),最终导致sendingFinalSuccessRepsonse里没触发res.status(200)的调用。
另外你当前的mockRequest和mockResponse使用了全局变量,多次测试会导致状态污染,也需要调整。
1. 关键修复步骤
(1)Mock axios模块,拦截外部请求
单元测试需要隔离外部依赖,用jest.mock mock整个axios模块,预设返回符合SuccessStruct结构的响应数据。
(2)修复mock对象的创建逻辑
每次调用mock函数时创建新对象,避免全局变量导致的状态污染。
(3)匹配axios响应结构与SuccessStruct
注意axios默认返回结构是{ data, status, statusText, headers, config },你需要把它转换成符合SuccessStruct的格式,否则data.statusCode会是undefined,无法触发目标分支。
修改后的完整测试代码
import { Request, Response, NextFunction } from "express" import { Credit } from "./credit.controller" import axios from "axios" // Mock整个axios模块 jest.mock('axios'); const mockedAxios = axios as jest.Mocked<typeof axios>; // 每次创建全新的mock请求对象 const mockRequest = () => { return { query: { userType: "xy", customerNumber : "42324242" } } as unknown as Request; } // 每次创建全新的mock响应对象 const mockResponse = () => { const res: Partial<Response> = {}; res.status = jest.fn().mockReturnValue(res); res.send = jest.fn().mockReturnValue(res); return res as Response; } describe("Get credit details", () => { it("should return 200 response when request succeeds", async () => { const req = mockRequest(); const res = mockResponse(); const next: NextFunction = jest.fn(); // 预设axios.get的返回值,匹配SuccessStruct结构 mockedAxios.get.mockResolvedValue({ status: 200, // axios原生返回的是status字段 data: { /* 这里放接口返回的实际数据 */ } }); await Credit(req, res, next); expect(res.status).toBeCalledWith(200); expect(res.send).toHaveBeenCalled(); expect(next).not.toHaveBeenCalled(); }); it("should call next with error when axios request fails", async () => { const req = mockRequest(); const res = mockResponse(); const next: NextFunction = jest.fn(); const testError = new Error("External request failed"); mockedAxios.get.mockRejectedValue(testError); await Credit(req, res, next); expect(next).toBeCalledWith(testError); expect(res.status).not.toHaveBeenCalled(); }); });
控制器代码调整(必要)
需要把axios的响应转换成SuccessStruct格式,否则statusCode字段不存在:
const Credit = async(req : Request, res: Response, next: NextFunction) => { try { const axiosResponse = await axios.get("some URL"); // 转换为SuccessStruct结构 const successData: interfaces.SuccessStruct = { statusCode: axiosResponse.status, data: axiosResponse.data // 补充SuccessStruct要求的其他字段 }; sendingFinalSuccessRepsonse(res, next, successData); } catch (error) { next(error); } }
内容的提问来源于stack exchange,提问作者Rupali Singh
相关产品推荐
相关产品推荐

