如何在Django模板中为含jQuery的JS函数编写Jest单元测试
解决Django+jQuery项目的Jest单元测试兼容问题
问题1:测试时无法识别jQuery
解决方案:正确Mock jQuery模块
你之前的测试文件中Mock jQuery的语法存在重复且逻辑不完善的问题,需要统一Mock并让$.ajax返回Promise(适配原函数的async/await逻辑)。修改setup.test.js如下:
// Mock整个jQuery模块,指定返回的对象结构 jest.mock('jquery', () => ({ // 让$.ajax返回一个已resolve的Promise,模拟异步请求成功 ajax: jest.fn(() => Promise.resolve({ mockResponse: 'success' })) })); // 导入Mock后的jQuery和myFunction const $ = require('jquery'); const { myFunction } = require('../setup'); test('myFunction应调用$.ajax并返回数据', async () => { const result = await myFunction(); // 验证$.ajax被调用过 expect($.ajax).toHaveBeenCalled(); // 验证返回结果与Mock数据一致 expect(result).toEqual({ mockResponse: 'success' }); });
问题2:导出函数后浏览器报错
解决方案:使用UMD兼容写法(同时支持浏览器全局和模块导入)
直接添加export属于ES模块语法,普通浏览器script标签无法解析,需要让setup.js同时兼容浏览器全局变量和Node.js模块系统。修改setup.js如下:
async function myFunction() { // 保留你的业务逻辑,示例中包含实际请求配置 const res = await $.ajax({ url: '/api/data/', method: 'GET' }); return res; } // UMD兼容逻辑:根据运行环境选择导出方式 if (typeof module !== 'undefined' && module.exports) { // Node.js/Jest环境:以模块形式导出 module.exports = { myFunction }; } else { // 浏览器环境:挂载到全局window对象 window.myFunction = myFunction; }
修改后:
- 在Django模板的
index.html中,仍可直接调用myFunction()(已挂载到window全局) - 在Jest测试中,可通过
require或import导入myFunction,不会触发语法错误
你之前尝试失败的原因
- 普通script中使用
import:浏览器默认不支持在非模块脚本中使用import,若要启用需将script标签改为<script type="module">,但会引发模块路径解析问题(Django的static URL不符合模块路径规则),因此UMD写法更适配该场景。 - 重复且不完善的jQuery Mock:你之前的测试文件中同时调用了无参数和带工厂函数的
jest.mock('jquery'),且Mock的ajax未返回Promise,导致原函数的await无法处理,最终出现$.ajax is not a function错误。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

