Jest运行测试报TypeError: getSomething is not a function排查
问题根因
报错核心是导入语法与导出语法不匹配:SomeService.js中使用export default导出的是整个SomeService类,getSomething是挂载在类上的静态方法,并没有作为单独的具名导出暴露。测试文件中使用import { getSomething }的具名解构语法,本质是在找文件里不存在的名为getSomething的独立导出变量,自然会拿到undefined,调用时就会抛出"is not a function"的错误。
除此之外原测试代码还有4处会导致后续测试失败的隐含问题:
- 未处理异步逻辑:
getSomething返回Promise,原测试没有等待异步执行完成就做断言,会出现断言时序错误 - mock返回值不符合业务逻辑:业务代码中取的是接口响应的
result.data字段,原mock直接返回数组,会导致最终拿到的结果不符合预期 - 接口调用参数断言不完整:原断言只校验了请求url,漏了第二个params参数,无法覆盖传参逻辑
- 失败场景测试逻辑与业务代码不符:业务代码catch块是直接抛出错误,并没有返回空实体的逻辑,原测试用例描述和实际逻辑不一致
修复方案
- 修正导入语法,导入默认导出的类,而非解构不存在的具名方法:
// 替换原错误的import { getSomething } 写法 import SomeService from "../SomeService.js"; - 调整静态方法调用方式,通过类名直接调用静态方法,同时给测试用例加async/await处理异步逻辑,修正mock返回值结构,补全参数断言:
修复后的完整测试代码如下:import axios from "axios"; import SomeService from "../SomeService.js"; // 注意补全项目中Constants、API_BASE_URL的对应导入/测试环境全局配置 import Constants from "你的Constants实际引入路径"; jest.mock("axios"); describe("getSomething", () => { describe("when API call is successful", () => { it("should return some details", async () => { // given const testId = 123; const mockRes = { data: [ { id: 1, name: "Something 1" }, { id: 2, name: "Something 2" }, ] }; axios.get.mockResolvedValueOnce(mockRes); // when const result = await SomeService.getSomething(testId); // then const targetUrl = API_BASE_URL + Constants.API_URL_Something; expect(axios.get).toHaveBeenCalledWith(targetUrl, { params: { id: testId } }); expect(result).toEqual(mockRes.data); }); }); describe("when API call fails", () => { it("should throw the caught request error", async () => { // given const testId = 123; const mockError = new Error("network error"); axios.get.mockRejectedValueOnce(mockError); // then await expect(SomeService.getSomething(testId)).rejects.toThrow(mockError); }); }); });
不需要修改业务类的静态方法写法,也不需要调整导出语法,只需要修正测试文件的导入和调用逻辑即可。
内容的提问来源于stack exchange,提问作者AIK DO
相关产品推荐
相关产品推荐

