如何使用jest模拟mssql包的SQL Server ConnectionPool数据库连接
解决方案
你的mock不生效的核心原因是没有完整模拟mssql模块的链式调用结构:new ConnectionPool()生成的实例需要包含connect、request方法,request()返回的实例需要包含input、query方法,你之前只 mock 了connect方法,后续调用的方法都是未定义状态。
完整可运行测试代码
import { DBConnection } from './db'; import sql from 'mssql'; // 模拟整个mssql模块 jest.mock('mssql'); // 定义request对象的mock,支持链式调用 const mockRequest = { input: jest.fn().mockReturnThis(), query: jest.fn().mockResolvedValue({ recordset: [{ key: 'key1' }] // 匹配SQL语句的OUTPUT返回结构 }) }; // 定义ConnectionPool实例的mock const mockPoolInstance = { connect: jest.fn().mockResolvedValue(true), request: jest.fn().mockReturnValue(mockRequest) }; // 绑定ConnectionPool构造函数的返回值为我们的mock实例 (sql.ConnectionPool as jest.Mock).mockImplementation(() => mockPoolInstance); const db = new DBConnection(); describe('DB test', () => { afterEach(() => { jest.clearAllMocks(); }); it('should have success response', async () => { const input = { key: 'key1', value: 1234 }; const response = await db.query(input); // 原业务代码直接返回request.query的完整结果,如需直接拿到key可调整业务代码的return逻辑 expect(response.recordset[0].key).toBe('key1'); // 可选:验证各方法调用参数符合预期 expect(sql.ConnectionPool).toHaveBeenCalledWith(expect.objectContaining({ server: "server", port: 1234, database: "db", user: "user", password: "password", trustServerCertificate: true })); expect(mockPoolInstance.connect).toHaveBeenCalled(); expect(mockRequest.input).toHaveBeenNthCalledWith(1, 'key', sql.VarChar, input.key); expect(mockRequest.input).toHaveBeenNthCalledWith(2, 'value', sql.VarChar, input.value); expect(mockRequest.query).toHaveBeenCalledWith("INSERT INTO SOMETABLE (key, value) OUTPUT INSERTED.key VALUES (@key, @value)"); }); });
关键实现说明
mockReturnThis()用来适配request.input().input().query()的链式调用写法- 直接通过
mockImplementation绑定构造函数的返回实例,比监听原型方法更简单直观,不会出现实例方法不匹配的问题 - 严格对齐
mssql原生的返回结构,避免结构不匹配导致的逻辑错误或断言失败
内容的提问来源于stack exchange,提问作者spinoza
相关产品推荐
相关产品推荐

