如何用Jest模拟函数内new创建的MSSQL Connection Pool?
无需重构即可用Jest模拟MSSQL ConnectionPool的方案
完全可以不用IOC重构,直接通过Jest的模块模拟能力实现对MSSQL连接池及execute方法的Mock,核心是链式mock住mssql模块里的ConnectionPool及后续的调用链。
具体实现步骤
Mock整个mssql模块
在测试文件开头用jest.mock('mssql')自动mock模块,再手动指定各个方法的返回值。链式Mock调用流程
针对代码里new ConnectionPool().connect().request().input().execute()的链式调用,需要逐层mock每个环节的返回值:
- 让
ConnectionPool构造函数返回包含connect方法的对象 connect方法返回Promise,resolve出包含request方法的pool对象request方法返回包含input和execute方法的request对象input方法返回自身(支持链式调用)execute方法返回预设的模拟数据
代码示例
假设你的业务代码(fetchData.js):
const sql = require('mssql'); const conn = require('./conn-config'); async function fetchData(...args) { const pool = await new sql.ConnectionPool(conn.getConfig()).connect(); const result = await pool.request().input(...args).execute('Get_Some_Data'); await pool.close(); // 后续业务逻辑 return result.recordset; } module.exports = fetchData;
对应的Jest测试代码(fetchData.test.js):
const sql = require('mssql'); const fetchData = require('./fetchData'); // 自动mock mssql模块 jest.mock('mssql'); describe('fetchData', () => { it('should return mock data from Get_Some_Data', async () => { // 定义模拟返回的数据 const mockRecordset = [{ id: 1, name: 'test data' }]; // Mock request对象的input和execute方法 const mockRequest = { input: jest.fn().mockReturnThis(), // input链式调用返回自身 execute: jest.fn().mockResolvedValue({ recordset: mockRecordset }) }; // Mock pool对象的request和close方法 const mockPool = { request: jest.fn().mockReturnValue(mockRequest), close: jest.fn().mockResolvedValue() }; // Mock ConnectionPool的connect方法 const mockConnect = jest.fn().mockResolvedValue(mockPool); sql.ConnectionPool.mockImplementation(() => ({ connect: mockConnect })); // 执行测试 const result = await fetchData('param1', 'param2'); // 断言验证 expect(sql.ConnectionPool).toHaveBeenCalled(); expect(mockConnect).toHaveBeenCalled(); expect(mockPool.request).toHaveBeenCalled(); expect(mockRequest.input).toHaveBeenCalledWith('param1', 'param2'); expect(mockRequest.execute).toHaveBeenCalledWith('Get_Some_Data'); expect(result).toEqual(mockRecordset); }); });
关键说明
mockImplementation用来覆盖ConnectionPool的构造逻辑,返回预设的带connect方法的对象mockReturnThis()保证input方法的链式调用能正常工作- 所有异步方法用
mockResolvedValue返回Promise格式的模拟数据,匹配实际代码的异步逻辑
这种方式不需要修改业务代码结构,完全通过Jest的模块模拟能力实现隔离测试,无需引入IOC。
内容的提问来源于stack exchange,提问作者uuid
相关产品推荐
相关产品推荐

