如何在TypeScript中使用Jest框架Mock MarkLogic客户端API
解决TypeScript中Jest Mock Marklogic的问题
问题分析
你的Mock代码存在几个关键问题导致不生效:
query方法Mock结构错误:原代码里dbRead.documents.query()返回的是包含result()方法的对象,而非直接返回Promise。你当前用mockResolvedValue直接返回函数,不符合原API的调用链逻辑。- 未Mock
marklogic.queryBuilder:原代码用到了qb.where(),不对这个对象Mock的话,测试时会抛出未定义错误。 - 测试逻辑不完整:仅定义了Mock实现,但没有调用目标业务函数,也没添加断言验证Mock是否触发。
修正后的测试代码
import marklogic from 'marklogic'; // 自动Mock整个marklogic模块 jest.mock('marklogic'); // 模拟documents对象的完整调用链 const mockResult = [{ uri: '/anypath', content: '' }]; const mockDocuments = { query: jest.fn().mockReturnValue({ // 模拟result()方法返回Promise result: jest.fn().mockResolvedValue(mockResult) }) }; // Mock queryBuilder的方法链 const mockQueryBuilder = { where: jest.fn().mockReturnThis(), slice: jest.fn().mockReturnThis() }; describe('文档查询逻辑测试', () => { beforeEach(() => { // 重置所有Mock调用记录 jest.clearAllMocks(); // 配置createDatabaseClient的Mock返回值 (marklogic.createDatabaseClient as jest.Mock).mockReturnValue({ documents: mockDocuments }); // 配置queryBuilder的Mock (marklogic.queryBuilder as jest.Mock).mockReturnValue(mockQueryBuilder); }); test('应正确获取并返回文档', async () => { // 封装你的业务逻辑(实际项目中可直接导入目标函数) const fetchDocuments = async () => { const connection = {}; // 替换为实际连接配置 const dbRead = marklogic.createDatabaseClient(connection); const qb = marklogic.queryBuilder; return dbRead.documents .query(qb.where().slice(0, 10000)) .result(); }; // 调用业务函数 const result = await fetchDocuments(); // 验证Mock调用 expect(marklogic.createDatabaseClient).toHaveBeenCalledTimes(1); expect(mockQueryBuilder.where).toHaveBeenCalled(); expect(mockQueryBuilder.slice).toHaveBeenCalledWith(0, 10000); expect(mockDocuments.query).toHaveBeenCalled(); expect(result).toEqual(mockResult); }); });
额外优化建议
- TypeScript类型规范:给返回的文档定义清晰的接口:
interface MarklogicDocument { uri: string; content: unknown; } interface DocumentsResult { forEach: (callback: (doc: MarklogicDocument) => void) => void; length: number; // 原代码中定义为string,实际应为number类型 }
- 用async/await简化异步逻辑:替代原代码的
then/catch写法,提升可读性:
try { const documents = await dbRead.documents .query(qb.where().slice(0, 10000)) .result() as DocumentsResult; // 处理文档逻辑 } catch (error) { // 错误处理 }
内容的提问来源于stack exchange,提问作者Shrikant
相关产品推荐
相关产品推荐

