Cypress测试执行数据库查询时触发util.promisify is not a function错误
问题:Cypress浏览器端执行SQL查询报错「util.promisify is not a function」
我遇到的「util.promisify is not a function」报错和其他讨论的情况不同——我并没有显式调用util.promisify函数。我想在Cypress测试中执行数据库查询,当前环境版本如下:
- Node 16.15.1
- Cypress 13.5.1
- TypeScript 5.0.2
- ts-node 10.9.1
- mssql 9.1.1
下面的数据库查询代码在服务端可以正常运行,但在Cypress浏览器端测试时出现报错:
Database文件代码
import sql from 'mssql'; export default class Database { private _databaseConnectionString; constructor() { this._databaseConnectionString = '已脱敏但有效的连接字符串'; }; async query(query: string) { try { await sql.connect(this._databaseConnectionString); const result = await sql.query(query); return result; } catch (errorMessage) { throw new Error(`查询数据库出错.\n${errorMessage}`); } } }
测试文件代码
import Database from "../../support/test_data/utilities/database"; const database = new Database(); describe('测试', () => { it('测试查询', () => { const aVariable = await database.query(`select * from Users`); }); });
我已经定位到触发异常的代码行:
await sql.connect(this._databaseConnectionString);
报错信息
- 在测试外部检测到未捕获的错误:
TypeError: 以下错误来自你的测试代码,而非Cypress。util.promisify is not a function
当Cypress检测到来自测试代码的未捕获错误时,会自动标记当前测试失败。
Cypress无法将此错误关联到任何特定测试。
我们动态生成了一个新测试来显示此失败。
我不知道该从何入手排查问题,请问有没有更优的在测试中执行SQL查询的方式?我是不是有根本性的操作错误?
解决方案
核心问题原因
你犯了一个根本性错误:直接在Cypress浏览器端代码中调用服务端数据库驱动(mssql)。
Cypress的测试代码分为两个运行环境:
- 浏览器端:运行在浏览器沙箱中,没有Node.js核心模块(比如
util),而mssql库依赖Node.js的util.promisify,所以触发报错。 - Node.js端(Cypress插件/任务):运行在本地Node环境中,可以正常调用服务端依赖。
正确实现方式
把数据库查询逻辑移到Cypress的tasks中,通过任务在Node.js环境执行查询:
- 在
cypress.config.ts中注册数据库查询任务:
import { defineConfig } from "cypress"; import sql from 'mssql'; export default defineConfig({ e2e: { setupNodeEvents(on, config) { // 注册数据库查询任务 on('task', { async queryDatabase(query: string) { const connectionString = '你的数据库连接字符串'; try { await sql.connect(connectionString); const result = await sql.query(query); return result; } catch (err) { throw new Error(`数据库查询失败: ${err}`); } finally { await sql.close(); // 确保连接关闭 } }, }); }, }, });
- 修改测试文件,通过
cy.task调用查询:
describe('测试', () => { it('测试数据库查询', async () => { const queryResult = await cy.task('queryDatabase', `select * from Users`); // 对查询结果做断言 expect(queryResult.recordset.length).to.be.greaterThan(0); }); });
额外优化建议
- 不要每次查询都新建连接,可以在插件中维护一个持久化连接,提升性能。
- 将数据库连接字符串放在环境变量中,避免硬编码(可通过
config.env读取)。 - 在任务中完善错误处理,确保连接异常时也能正常关闭。
内容的提问来源于stack exchange,提问作者Zuno
相关产品推荐
相关产品推荐

