Jest如何为模块模式导出的search方法配置各测试独有的mock实现
解决方案
问题根因
你当前的写法不生效有两个核心问题:
MyConnection是工厂函数,需要调用MyConnection()才会返回携带search方法的实例,直接修改MyConnection.search属于操作不存在的属性- 你之前Mock返回的
search是普通函数,不是Jest提供的Mock函数,本身不具备mockImplementation等Mock控制方法
正确实现步骤
步骤1:修正全局Mock定义
先把search定义为可修改的Jest Mock函数,确保所有生成的MyConnection实例都共享这个Mock的search方法:
// Jest 测试文件顶部 const MyConnection = require('../MyConnection') // 定义公共的search mock函数,后续可以直接修改它的实现 const mockSearch = jest.fn(() => ['mocked', 'fn', 'results']) jest.mock('../MyConnection', () => { return jest.fn(() => ({ search: mockSearch })) })
步骤2:每个用例单独修改Mock实现
在测试用例中直接修改mockSearch的实现即可,为了避免用例之间互相污染,可以加beforeEach重置Mock状态:
describe('connection tests', () => { // 每个测试执行前重置mock的调用记录和实现 beforeEach(() => { mockSearch.mockReset() }) it('test one', () => { // 单独设置当前用例的search实现 mockSearch.mockImplementation((q) => `You searched ${q}`) // 测试逻辑示例 const conn = MyConnection() expect(conn.search('test')).toBe('You searched test') }) it('test two', () => { mockSearch.mockImplementation((q) => q.length > 32 ? 'a' : 'b') // 测试逻辑示例 const conn = MyConnection() expect(conn.search('short str')).toBe('b') expect(conn.search('a'.repeat(33))).toBe('a') }) })
可选写法:通过Mock返回值获取实例修改
如果你不想把mockSearch提到外层作用域,也可以通过Jest Mock的调用结果获取生成的实例,再修改实例上的search方法:
// 全局Mock定义 jest.mock('../MyConnection', () => { return jest.fn(() => ({ search: jest.fn(() => ['mocked', 'fn', 'results']) })) }) // 测试用例内修改 it('test one', () => { const conn = MyConnection() conn.search.mockImplementation((q) => `You searched ${q}`) // 后续测试逻辑 })
如果MyConnection是在被测代码内部调用的,可以通过MyConnection.mock.results[0].value拿到被测代码生成的实例,再修改search实现即可。
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

