You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jasmine中mock函数?调用saveBooking未触发mock的checkStatus报错求助

问题根因

mock失效的核心原因有两点:

  1. Booking.js中saveBooking调用的是模块内部私有作用域下的checkStatus函数,而你用spyOn打桩的是模块导出对象module.exports上挂载的checkStatus属性,两者不是同一个引用,因此实际调用没有命中mock。
  2. 原有saveBooking没有返回内部的Promise链,await Booking.saveBooking(req)实际是等待了一个undefined,会在checkStatus异步执行完成前就触发断言,也会导致测试报错。

解决方案1:调整业务代码调用逻辑(成本最低)

修改Booking.js,让内部调用指向导出对象的方法,同时返回Promise链:

// Booking.js 修改后代码
const checkStatus = (id) => {
  // some code here
  return new Promise((resolve, reject)=>{
    resolve(value);
  });
}

const saveBooking =(req) => {
  // 1. 改为调用exports上的checkStatus,和mock的对象保持一致
  // 2. 加return把Promise暴露出去,await才能正常等待异步执行完成
  return module.exports.checkStatus(req.id).then(()=>{
    //save booking here ..
  }).catch((error)=>{
    throw new Error();
  });
}
    
module.exports = {saveBooking, checkStatus}

解决方案2:优化测试用例代码

你测试用例中使用的$q是AngularJS的异步工具,没有必要额外引入,直接用Jasmine内置的Promise mock方法即可:

// booking.Spec.js 修改后代码
const Booking = require('Booking');

describe('Booking',()=>{
  const req = {
    id: 2133,
    customer_name: 'John Smith',
    contact_number: '888-8888',
    contact_email: 'cam888@example.com'
  };

  it('Should check the status', async ()=>{
    // 简化mock逻辑,直接返回resolve的Promise
    spyOn(Booking, "checkStatus").and.resolveTo(true);
  
    await Booking.saveBooking(req);
    expect(Booking.checkStatus).toHaveBeenCalledWith(req.id); // 增加参数校验逻辑更严谨
  });
});

可选方案:不修改业务代码mock私有函数

如果不想调整业务代码的调用逻辑,可以引入rewire模块直接修改模块内部的私有checkStatus变量,也能实现mock效果。

内容的提问来源于stack exchange,提问作者cam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 02:54:08