如何Mock mysql2的getConnection?测试超时问题求助
解决ts-mockito无法mock mysql2 Pool.getConnection导致的测试超时问题
问题根因
测试卡在await this.pool.getConnection()超时,主要有两个核心原因:
- ts-mockito对mysql2的Pool类方法代理存在兼容性问题,导致mock的
getConnection方法未正确返回resolved状态的Promise - 业务代码中拿到连接后执行的后续异步操作(比如
conn.query、conn.release)未被mock,使得整个Promise链始终处于pending状态,最终触发超时
可行解决方案
方案1:手动模拟Pool对象(绕过ts-mockito兼容性问题)
直接创建符合Pool类型定义的模拟对象,手动实现需要的方法,这种方式稳定性更高:
import { Pool, PoolConnection } from "mysql2/promise"; import Service from './'; import { expect } from 'chai'; describe("Conn test", function() { // 模拟PoolConnection,实现业务中用到的所有方法 const mockConn: Partial<PoolConnection> = { query: async () => [[], []], // 根据业务实际返回值调整 release: async () => {} }; // 模拟Pool的getConnection方法 const mockPool: Partial<Pool> = { getConnection: async () => mockConn as PoolConnection }; const service = new Service(mockPool as Pool); it("Should save info", async function() { const res = await service.saveInfo("test content"); expect(res).to.be.ok; // 替换成你的实际断言逻辑 // 验证方法调用情况 expect(mockPool.getConnection).to.have.been.called; expect(mockConn.query).to.have.been.called; }); });
方案2:调整ts-mockito使用逻辑,补全所有必要的mock
如果坚持使用ts-mockito,必须确保业务中用到的PoolConnection的所有异步方法都被mock返回resolved状态的Promise:
import { Pool, PoolConnection } from "mysql2/promise"; import { mock, instance, verify, when, anyString } from "ts-mockito"; import Service from './'; import { expect } from 'chai'; describe("Conn test", function() { const connPool = mock<Pool>(); const connection = mock<PoolConnection>(); // mock getConnection返回模拟连接 when(connPool.getConnection()).thenResolve(instance(connection)); // 必须mock业务中用到的connection方法,比如query、release when(connection.query(anyString())).thenResolve([[], []]); when(connection.release()).thenResolve(); const service = new Service(instance(connPool)); it("Should save info", async function() { const res = await service.saveInfo("test content"); expect(res).to.not.throw; // 验证调用 verify(connPool.getConnection()).called(); verify(connection.query(anyString())).called(); }); });
重要提示
- 业务代码中
saveInfo方法内,只要有基于PoolConnection的异步操作,就必须全部mock返回resolved状态的Promise,否则会导致整个异步流程卡住 - 部分第三方库的类方法可能和ts-mockito的代理逻辑存在冲突,此时手动模拟对象是更可靠的选择
内容的提问来源于stack exchange,提问作者Ivan Pandžić
相关产品推荐
相关产品推荐

