Node.js中如何获取两个异步回调的布尔值以完成数据库查询函数测试
问题1:不修改现有getCompanyById函数能否实现测试逻辑
可以实现,无需改动原有业务代码,提供两种可行方案:
方案1:回调计数器
通过计数器统计已完成的异步请求数量,所有请求返回后再统一校验结果:
function testGetCompanyById() { let finishedCount = 0; let pass1 = false, pass2 = false; // 所有请求完成后执行校验 const validateResult = () => { if (finishedCount === 2) { const allPassed = pass1 && pass2; console.log("Test for getCompanyById() passed: " + allPassed); } }; databaseConnection.getCompanyById(1, function (company) { pass1 = company.first_name === "Harald" && company.last_name === "Schmidt" && company.id_schoolAdmin === 1; finishedCount++; validateResult(); }); databaseConnection.getCompanyById(2, function (company) { pass2 = company.first_name === "Madeline" && company.last_name === "Müller" && company.id_schoolAdmin === 2; finishedCount++; validateResult(); }); }
方案2:包装为Promise后批量等待
使用Node.js内置的util.promisify工具将回调风格的函数转为返回Promise的函数,再通过Promise.all等待所有请求完成:
const { promisify } = require('util'); // 绑定上下文避免this指向错误 const getCompanyByIdAsync = promisify(databaseConnection.getCompanyById.bind(databaseConnection)); async function testGetCompanyById() { // 并行执行两个查询,全部返回后再执行后续逻辑 const [company1, company2] = await Promise.all([ getCompanyByIdAsync(1), getCompanyByIdAsync(2) ]); const pass1 = company1.first_name === "Harald" && company1.last_name === "Schmidt" && company1.id_schoolAdmin === 1; const pass2 = company2.first_name === "Madeline" && company2.last_name === "Müller" && company2.id_schoolAdmin === 2; console.log("Test for getCompanyById() passed: " + (pass1 && pass2)); }
问题2:修改原函数的更优实现方式
推荐将原函数改为返回Promise的写法,相比回调嵌套可读性更强,也能直接适配async/await语法,避免回调地狱问题,修改后的代码如下:
getCompanyById(id) { return new Promise((resolve, reject) => { let company = null; this.db.query("SELECT * FROM Company where id=?", id) .on('result', (data) => { company = data; }) .on('end', () => { resolve(company); }) .on('error', (err) => { // 新增错误抛出逻辑,方便上层捕获处理异常 reject(err); }); }); }
修改后业务调用和测试都可以直接用async/await编写,逻辑更清晰。
问题3:适合的异步测试框架
目前主流的Node.js测试框架都天然支持异步场景,推荐以下两种选择:
- Jest:开箱即用,配置简单,内置断言、Mock能力,同时支持回调、Promise、async/await多种异步测试写法,对新手友好
- Mocha + Chai:灵活性更高,可以自由搭配断言库、插件,适合有定制化测试需求的场景
以Jest为例,测试用例编写非常简洁:
test('getCompanyById查询结果符合预期', async () => { const company1 = await databaseConnection.getCompanyById(1); expect(company1).toMatchObject({ first_name: "Harald", last_name: "Schmidt", id_schoolAdmin: 1 }); const company2 = await databaseConnection.getCompanyById(2); expect(company2).toMatchObject({ first_name: "Madeline", last_name: "Müller", id_schoolAdmin: 2 }); });
注:你原有测试代码中调用的
getSchoolAdministrationById为笔误,实际函数名应为getCompanyById
内容的提问来源于stack exchange,提问作者diveincode
相关产品推荐
相关产品推荐

