如何用Jest测试MySQL createConnection响应?及相关测试疑问
MySQL连接测试相关问题解答
1. 接下来该如何推进测试?
你当前的代码仅完成了连接创建,未做任何有效性验证,可从以下方向完善:
- 验证连接实例合法性:断言创建后的
connection不是null或undefined,确保函数返回了有效对象 - 验证连接可用性:执行简单测试查询(如
SELECT 1),确认连接能正常与数据库通信 - 捕获连接错误:处理连接失败场景,确保测试能识别异常
- 清理资源:测试结束后关闭连接,避免占用数据库连接池资源
修改后的测试代码示例(Jest + TypeScript):
import mysql from 'mysql2/promise'; import dotenv from 'dotenv'; dotenv.config(); test("Create connection successfully", async () => { const connectionOptions = { host: process.env.Database_host, user: process.env.Database_User, password: process.env.Database_Password, database: process.env.database_Name, }; let connection; try { connection = await mysql.createConnection(connectionOptions); // 断言连接实例存在 expect(connection).toBeDefined(); expect(connection).not.toBeNull(); // 执行测试查询验证连接可用 const [rows] = await connection.execute('SELECT 1'); expect(rows).toEqual([{ '1': 1 }]); } catch (error) { throw new Error(`Connection failed: ${(error as Error).message}`); } finally { // 无论成功失败,都关闭连接 if (connection) { await connection.end(); } } });
2. 是否需要换一种方式编写该测试?
如果目标是测试真实数据库连接,当前思路没问题,但可做优化让测试更健壮:
- 复用连接资源:用Jest的
beforeAll/afterAll钩子,在所有测试前创建一次连接,测试完成后统一关闭,减少重复开销 - 抽离配置:把数据库配置单独抽成模块,方便测试与业务代码复用
- 隔离测试环境:确保使用专门的测试数据库,避免污染生产数据
优化后的代码示例:
import mysql from 'mysql2/promise'; import dotenv from 'dotenv'; dotenv.config(); let connection: mysql.Connection | undefined; beforeAll(async () => { const connectionOptions = { host: process.env.Database_host, user: process.env.Database_User, password: process.env.Database_Password, database: process.env.database_Name, }; connection = await mysql.createConnection(connectionOptions); }); afterAll(async () => { if (connection) { await connection.end(); } }); test("Connection instance is valid", () => { expect(connection).toBeDefined(); expect(connection).not.toBeNull(); }); test("Connection can execute queries", async () => { if (!connection) throw new Error("Connection not initialized"); const [rows] = await connection.execute('SELECT 1'); expect(rows).toEqual([{ '1': 1 }]); });
如果要做严格意义上的单元测试,则需用Mock替代真实数据库(如jest.mock('mysql2/promise')模拟createConnection返回),但你明确要测试真实连接,当前方式更贴合需求。
3. 若不使用Jest,该如何验证函数的响应是否成功?
可使用Node.js原生assert模块,或自定义验证逻辑编写脚本:
方式1:原生assert模块
import mysql from 'mysql2/promise'; import assert from 'assert/strict'; import dotenv from 'dotenv'; dotenv.config(); async function testConnection() { const connectionOptions = { host: process.env.Database_host, user: process.env.Database_User, password: process.env.Database_Password, database: process.env.database_Name, }; let connection; try { connection = await mysql.createConnection(connectionOptions); assert.ok(connection, 'Connection instance is null or undefined'); assert.ok(typeof connection.execute === 'function', 'Connection lacks execute method'); const [rows] = await connection.execute('SELECT 1'); assert.deepEqual(rows, [{ '1': 1 }], 'Test query returned unexpected result'); console.log('Connection test passed!'); } catch (error) { console.error('Connection test failed:', (error as Error).message); process.exit(1); } finally { if (connection) { await connection.end(); } } } testConnection();
方式2:自定义验证逻辑
import mysql from 'mysql2/promise'; import dotenv from 'dotenv'; dotenv.config(); async function testConnection() { const connectionOptions = { host: process.env.Database_host, user: process.env.Database_User, password: process.env.Database_Password, database: process.env.database_Name, }; let connection; try { connection = await mysql.createConnection(connectionOptions); if (!connection) { throw new Error('Failed to create connection instance'); } const [rows] = await connection.execute('SELECT 1'); if (!Array.isArray(rows) || rows.length !== 1 || rows[0]['1'] !== 1) { throw new Error('Test query result is invalid'); } console.log('Connection test passed!'); } catch (error) { console.error('Connection test failed:', (error as Error).message); process.exit(1); } finally { if (connection) { await connection.end(); } } } testConnection();
内容的提问来源于stack exchange,提问作者Karim Fayed
相关产品推荐
相关产品推荐

