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
相关产品推荐
相关产品推荐

