Jest中不mock axios直接mock调用它的上层函数为何测试失效
测试失败原因
- 核心原因:Node.js 模块的作用域绑定问题。你在测试中修改的只是
server模块导出对象上的loadUser属性,但fullNameGen内部直接调用的是模块私有作用域中定义的原生loadUser函数,和导出对象的属性没有关联,因此你的mock完全没有生效,代码还是走了原函数的真实axios请求,拿到了线上返回的Janet Weaver数据。 - 额外笔误:一是你mock返回的
first_name值为rav,但断言写的是期望ravi shekhar,值不匹配;二是你没有对fullNameGen做mock处理,直接断言server.fullNameGen被调用1次必然失败。
修正方案
如果你要实现不mock axios、只mockloadUser的测试逻辑,需要调整源文件的调用方式,让fullNameGen调用模块导出对象上的loadUser,这样你修改导出对象的mock才会生效:
步骤1:修改server.js的fullNameGen逻辑
// server.js 仅修改fullNameGen内部的loadUser调用即可 function fullNameGen(){ return new Promise((res,rej)=>{ // 把原本的loadUser()改为调用module.exports.loadUser() module.exports.loadUser().then(({data:info})=>{ console.log(info.data); res(info.data.first_name+" "+info.data.last_name); }).catch((err)=>{ console.log(err.message); rej(err.message); }) }) }
步骤2:修正测试文件代码
const server = require('./server'); test("Check full Name generation",async()=>{ // 用spyOn绑定loadUser的mock,更易清理 const mockLoadUser = jest.spyOn(server, 'loadUser').mockResolvedValue({ data:{ data:{ first_name:"rav", last_name:"shekhar" } } }); const result = await server.fullNameGen(); // 断言和mock返回值保持一致 expect(result).toBe("rav shekhar"); // 正确断言loadUser被调用1次 expect(mockLoadUser).toBeCalledTimes(1); // 清理mock避免影响其他用例 mockLoadUser.mockRestore(); })
改完后测试即可正常通过,不会触发真实的axios请求。
内容的提问来源于stack exchange,提问作者ravi shekhar
相关产品推荐
相关产品推荐

