如何在Jest中Mock mysql/promise的createConnection函数
使用Jest Mock MySQL连接测试TypeScript的read类
要隔离测试你的read类,核心是Mock mysql/promise模块中的createConnection函数,以及连接对象的query方法,完全避免真实数据库交互。以下是针对不同场景的具体实现方案:
1. 基础Mock配置
首先在测试文件中Mock整个mysql/promise模块,同时处理TypeScript的类型兼容问题:
import { read } from './path-to-your-read-class'; import * as mysql from 'mysql/promise'; import { Connection, ConnectionOptions, RowDataPacket } from 'mysql/promise'; // Mock整个mysql/promise模块 jest.mock('mysql/promise'); // 为Mock的createConnection添加类型断言 const mockCreateConnection = jest.mocked(mysql.createConnection);
2. 场景测试案例
场景1:查询成功,返回正常数据
Mock连接成功建立,且query方法返回预设的查询结果:
test('read方法应返回查询到的数据', async () => { // 预设模拟的查询结果 const mockResults: RowDataPacket[] = [ { id: 1, name: 'test-data-1' }, { id: 2, name: 'test-data-2' } ]; // Mock连接对象的query方法 const mockQuery = jest.fn().mockResolvedValue([mockResults]); // Mock createConnection返回带有query方法的连接对象 mockCreateConnection.mockResolvedValue({ query: mockQuery } as unknown as Connection); // 实例化read类并调用方法 const testOptions: ConnectionOptions = { host: 'localhost', user: 'test', password: 'test', database: 'test' }; const reader = new read(testOptions); const results = await reader.read('test_table'); // 断言结果符合预期 expect(results).toEqual(mockResults); // 断言createConnection被正确调用 expect(mockCreateConnection).toHaveBeenCalledWith(testOptions); // 断言query被调用了正确的SQL语句 expect(mockQuery).toHaveBeenCalledWith('SELECT * FROM test_table'); });
场景2:查询返回空结果
只需修改预设的结果为空数组即可:
test('read方法应返回空数组当表中无数据', async () => { const mockEmptyResults: RowDataPacket[] = []; const mockQuery = jest.fn().mockResolvedValue([mockEmptyResults]); mockCreateConnection.mockResolvedValue({ query: mockQuery } as unknown as Connection); const reader = new read({} as ConnectionOptions); const results = await reader.read('empty_table'); expect(results).toEqual([]); expect(mockQuery).toHaveBeenCalledWith('SELECT * FROM empty_table'); });
场景3:数据库连接失败
Mock createConnection抛出错误,测试方法是否正确传递错误:
test('read方法应在连接失败时抛出错误', async () => { const mockError = new Error('数据库连接超时'); mockCreateConnection.mockRejectedValue(mockError); const reader = new read({} as ConnectionOptions); // 断言方法抛出预期错误 await expect(reader.read('test_table')).rejects.toThrow(mockError); expect(mockCreateConnection).toHaveBeenCalled(); });
场景4:查询执行失败
Mock连接成功建立,但query方法抛出错误:
test('read方法应在查询失败时抛出错误', async () => { const mockQueryError = new Error('SQL语法错误'); const mockQuery = jest.fn().mockRejectedValue(mockQueryError); mockCreateConnection.mockResolvedValue({ query: mockQuery } as unknown as Connection); const reader = new read({} as ConnectionOptions); await expect(reader.read('invalid_table')).rejects.toThrow(mockQueryError); expect(mockQuery).toHaveBeenCalledWith('SELECT * FROM invalid_table'); });
注意事项
- 每次测试前可以用
jest.clearAllMocks()清除Mock的调用记录,避免测试间的干扰 - TypeScript类型断言(
as unknown as Connection)是因为我们只Mock了需要的query方法,完整的Connection对象包含更多属性,但测试中无需关心
内容的提问来源于stack exchange,提问作者BoazBitt
相关产品推荐
相关产品推荐

