Jest如何Mock导出命名空间下的类 以TypeScript Gremlin项目为例
解决方案
不需要手动实现process命名空间下两个类的所有扩展方法,可通过Jest Mock + Proxy代理的方式实现自动链式调用,同时兼容@types/gremlin的类型校验。
具体实现步骤
1. 编写全局Mock文件
在项目根目录新建__mocks__/gremlin.ts,写入如下内容:
import type * as gremlin from 'gremlin'; // Mock GraphTraversal 实例,用Proxy自动处理所有方法调用,返回自身实现链式调用 export const mockGraphTraversal = new Proxy({}, { get(target, propKey) { // 若为Jest内置Mock属性直接返回,否则返回返回自身的Mock函数 if (propKey in target) { return Reflect.get(target, propKey); } return jest.fn(() => mockGraphTraversal); } }) as unknown as jest.Mocked<gremlin.process.GraphTraversal>; // Mock GraphTraversalSource 实例 export const mockGraphTraversalSource = new Proxy({ V: jest.fn(() => mockGraphTraversal) }, { get(target, propKey) { if (propKey in target) { return Reflect.get(target, propKey); } // 其他根方法如addV、E等也会自动生成Mock,返回GraphTraversal实例 return jest.fn(() => mockGraphTraversal); } }) as unknown as jest.Mocked<gremlin.process.GraphTraversalSource>; // 导出Mock后的process命名空间 export const process: typeof gremlin.process = { ...jest.requireActual<typeof gremlin>('gremlin').process, GraphTraversal: jest.fn(() => mockGraphTraversal) as any, GraphTraversalSource: jest.fn(() => mockGraphTraversalSource) as any }; // 其余未Mock的gremlin导出保留原始实现 export * from 'gremlin';
2. 测试中启用Mock
在需要Mock Gremlin的测试文件开头,添加以下代码启用全局Mock:
jest.mock('gremlin');
3. 自定义逻辑与断言(可选)
如果需要验证方法调用参数、自定义特定方法的返回值,可直接操作导出的Mock实例:
import { process, mockGraphTraversalSource, mockGraphTraversal } from 'gremlin'; // 示例:验证g.V('123').has('name','张三')调用是否符合预期 test('gremlin traversal test', () => { // 执行业务代码 yourBusinessFunction(); // 断言V方法传入参数为123 expect(mockGraphTraversalSource.V).toHaveBeenCalledWith('123'); // 断言has方法传入参数正确 expect(mockGraphTraversal.has).toHaveBeenCalledWith('name', '张三'); })
类型兼容说明
实现中通过as unknown as做类型断言,完全匹配@types/gremlin@3.4.6的类型定义,不会出现TS编译报错。如果用到了process下的其他成员,可在Mock的process对象中按需补充配置。
内容的提问来源于stack exchange,提问作者Joe Kennedy
相关产品推荐
相关产品推荐

