使用Jest测试Ajax请求时出现TypeError: $.ajax is not a function错误求助
解决Jest测试中jQuery $.ajax未定义的问题及正确测试方法
问题根源
- 全局变量未挂载:浏览器中通过script标签引入jQuery时,
$会成为全局window对象的属性,但Jest运行在Node.js环境,默认没有全局的window或$,导致你的函数找不到$.ajax。 - 测试代码的Spy写法错误:你当前的
jest.spyOn(sendQuestion.sendESGPIC(), 'ajax')是错误的——sendESGPIC()是执行函数,它本身没有ajax属性,你需要监听的是$.ajax方法。
解决方案步骤
1. 正确配置Jest中的全局jQuery
你有两种方式让测试代码中的函数能访问到$:
方式一:在测试文件中手动挂载全局$
在测试文件开头,导入jQuery后将其挂载到全局对象:
var $ = require("jquery"); // 模拟浏览器的全局window和$ global.$ = $; global.window = global; var sendQuestion = require("./path/to/sendQuestion.js"); // 替换为你的实际文件路径
方式二:通过Jest配置文件全局引入jQuery
在项目根目录的jest.config.js中添加setupFiles配置,指定一个初始化文件来挂载全局jQuery:
// jest.config.js module.exports = { setupFiles: ["./jest.setup.js"] };
然后创建jest.setup.js文件:
// jest.setup.js const $ = require('jquery'); global.$ = $; global.window = global;
2. 修正测试代码中的Spy逻辑
你的测试代码存在两个问题:
- Spy的目标错误,应该监听
$.ajax而不是sendESGPIC的属性 - 调用
sendESGPIC时没有传入函数要求的results参数
修正后的测试代码:
describe("Ajax sendQuestion", () => { beforeEach(() => { jest.restoreAllMocks(); // 每次测试前重置ajax的spy并模拟空实现 jest.spyOn($, 'ajax').mockImplementation(() => {}); }); const $ = require("jquery"); global.$ = $; const sendQuestion = require("./path/to/sendQuestion.js"); test('sendESGPIC should call $.ajax with correct parameters', () => { const mockResults = { key: 'test-data' }; // 模拟传入的测试数据 sendQuestion.sendESGPIC(mockResults); expect($.ajax).toHaveBeenCalledWith({ url: "PATH", // 替换为函数中实际的接口路径 contentType: "application/json", data: JSON.stringify(mockResults), type: 'POST', success: expect.any(Function), error: expect.any(Function), }); }); })
3. 额外注意事项
- 如果你的
sendESGPIC函数是直接写在全局作用域(没有模块导出),需要调整代码结构,在sendQuestion.js末尾添加导出语句:// 在sendQuestion.js文件末尾 module.exports = { sendESGPIC }; - 确保安装了jQuery依赖:如果项目之前仅通过CDN引入,需要执行
npm install jquery --save-dev安装本地依赖供Jest使用。
内容的提问来源于stack exchange,提问作者Martijn Noordhof
相关产品推荐
相关产品推荐

