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

Jest使用__mocks__模拟模块后spyOn监听失败及自定义mock实现问题

问题根因

你当前监听失效的核心原因是:测试文件中你自行实例化的MyController对象,与业务代码内部实例化的MyController对象是两个完全独立的实例,你给测试侧实例的方法打监听,自然无法捕获业务侧实例的方法调用。

问题1:正确监听setAvailability调用

推荐直接监听类原型上的方法,所有实例的方法调用都会走原型逻辑,无需修改现有__mocks__目录下的代码,修改测试文件即可:

const { MyController } = require('DB-Utils');

describe('Register Tests', () => {
  // 每次测试后恢复mock,避免用例间污染
  afterEach(() => {
    jest.restoreAllMocks();
  });

  fit('myController setAvailability', async () => {
    // 监听原型上的setAvailability方法,默认返回原mock的true
    const spy = jest.spyOn(MyController.prototype, 'setAvailability').mockResolvedValue(true);
    
    // ---这里写调用业务逻辑的代码---
    await yourBusinessCode();

    // 直接断言原型上的spy即可
    expect(spy).toHaveBeenCalledWith('foo', 'bar');
  });
});

问题2:覆写方法实现抛出异常

只需修改spy的mockImplementation逻辑即可,注意setAvailability是异步方法,抛出的是拒绝状态的Promise,需要用.rejects捕获异常:

fit('myController setAvailability throws', async () => {
  // 监听原型方法,修改实现为抛出异常
  jest.spyOn(MyController.prototype, 'setAvailability').mockRejectedValue(new Error('模拟异常'));
  
  // 异步异常断言需要加rejects,且前面加await
  await expect(
    // ---这里写调用业务逻辑的代码---
    yourBusinessCode()
  ).rejects.toThrow();
});

可选优化:提前把mock类的方法改为默认mock函数

如果不想每次都监听原型,可以直接修改__mocks__/controllers/myController.js,将方法默认定义为jest mock函数,后续所有实例的方法默认带调用统计能力:

class MyController {
  setAvailability = jest.fn().mockResolvedValue(true);
}

module.exports = {
  MyController,
};

之后测试时不需要再手动打spy,直接通过MyController.prototype.setAvailability就能拿到调用记录。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 12:45:05