Jest教程:如何Mock类中的特定方法
只Mock类中特定方法的两种实现方式
针对你的需求——Mock Person 类的 sayMyName 方法但保留 bla 的原有逻辑,这里有两种常用的Jest实现方案,分别适用于不同场景:
方法一:模块级Mock(所有实例生效)
这种方式会在模块层面替换类的构造逻辑,确保所有通过 new Person() 创建的实例都使用Mock后的 sayMyName,同时完整保留其他方法的原生逻辑:
const Person = require("../Person"); // 获取真实的Person类(绕过Jest的mock拦截,避免循环引用) const actualPerson = jest.requireActual('../Person'); jest.mock('../Person', () => { // 返回一个mock的构造函数 return jest.fn().mockImplementation((first, last) => { // 创建真实的Person实例,确保原生方法(比如bla)可用 const instance = new actualPerson.default(first, last); // 替换sayMyName为自定义的Mock实现 instance.sayMyName = jest.fn(() => console.log('Mocked sayMyName executed!')); // 返回处理后的实例 return instance; }); }); // 测试用例示例 test('mocks sayMyName while keeping bla intact', () => { const person = new Person('Alice', 'Smith'); // 验证Mock方法被调用 person.sayMyName(); expect(person.sayMyName).toHaveBeenCalled(); // 验证原生方法逻辑未被修改 expect(person.bla()).toBe('bla'); });
关键细节:
- 使用
jest.requireActual('../Person')获取真实的类定义:因为jest.mock会被提升到代码最顶部,直接require会拿到mock后的模块,requireActual可以绕过这个拦截,拿到原始类。 - 基于真实实例修改特定方法:这样既保留了所有原生方法的逻辑,又能精准替换目标方法。
方法二:实例级Mock(单个实例生效)
如果你只需要Mock某个特定实例的sayMyName方法,而非所有实例,使用jest.spyOn会更简洁灵活:
const Person = require("../Person"); test('mocks sayMyName for a single instance', () => { const person = new Person('Bob', 'Jones'); // 用spyOn监听并替换sayMyName方法 const mockSayMyName = jest.spyOn(person, 'sayMyName') .mockImplementation(() => console.log('Instance-specific mock!')); // 调用Mock方法 person.sayMyName(); expect(mockSayMyName).toHaveBeenCalled(); // 验证原生bla方法正常工作 expect(person.bla()).toBe('bla'); // 可选:测试结束后恢复原方法,避免影响其他测试用例 mockSayMyName.mockRestore(); });
优势:
- 无需修改模块级的mock配置,只针对当前测试用例中的实例生效,测试隔离性更好。
- 可以通过
mockRestore()快速恢复原方法,避免对后续测试产生干扰。
内容的提问来源于stack exchange,提问作者CrazySynthax
相关产品推荐
相关产品推荐

