Node.js跨文件函数返回值问题:获取结果为undefined
问题分析与解决方案
这个问题我之前也碰到过,核心原因是你混淆了Mocha测试框架的异步执行逻辑和普通函数的返回值处理,导致外部调用时始终拿到undefined。
为什么你的代码会返回undefined?
- Mocha的测试块是异步注册的:
describe、it这些函数是Mocha用来注册测试用例的,它们不会阻塞add函数的执行流程。你的add函数会直接执行完毕,返回默认的undefined,而add变量的赋值是在it的异步回调(.then里)中,这时候函数早就结束了,外部根本拿不到这个赋值后的结果。 - Mocha测试不是用来封装可复用逻辑的:
describe/it的作用是组织测试用例,需要通过Mocha命令运行,而不是作为普通函数调用并获取返回值。
正确的解决方式
根据你的需求,分两种场景处理:
场景1:封装WebdriverIO操作作为工具函数(供其他文件调用)
把WebdriverIO的逻辑封装成一个返回Promise的异步函数,去掉Mocha的测试块:
// add.js const webdriverio = require('webdriverio'); // 命名更清晰,明确函数作用 async function getGmailLinkText() { // 初始化driver const driver = webdriverio.remote({ desiredCapabilities: { browserName: 'chrome', chromeOptions: { args: ['--start-maximized'] } } }); try { // 启动浏览器 await driver.init(); // 打开谷歌页面 await driver.url("https://www.google.co.in/"); // 获取Gmail文本 const gmailText = await driver.getText("//a[text()='Gmail']"); // 返回结果 return gmailText; } catch (error) { console.error('操作出错:', error); throw error; // 抛出错误让调用方处理 } finally { // 无论成功失败,都关闭浏览器会话 await driver.end(); } } // 导出函数供其他文件使用 module.exports = { getGmailLinkText };
然后在另一个文件中调用这个异步函数(必须用async/await或者.then()处理异步结果):
// other-file.js const { getGmailLinkText } = require('./add.js'); // 使用async/await(推荐) async function run() { try { const text = await getGmailLinkText(); console.log('Gmail链接文本:', text); // 这里就能拿到正确结果了 } catch (err) { console.error('调用失败:', err); } } run(); // 或者用.then()链式调用 // getGmailLinkText() // .then(text => console.log('Gmail链接文本:', text)) // .catch(err => console.error('调用失败:', err));
场景2:如果是要写Mocha自动化测试
如果你的目的是编写测试用例,而不是给其他文件提供返回值,那应该保持Mocha的结构,但不需要从add函数返回值,而是直接在测试用例里断言结果:
// add.js const webdriverio = require('webdriverio'); describe('This is from add.js file', function() { this.timeout(50000); let driver; before(async function() { driver = webdriverio.remote({ desiredCapabilities: { browserName: 'chrome', chromeOptions: { args: ['--start-maximized'] } } }); await driver.init(); }); it('should get Gmail link text', async function() { await driver.url("https://www.google.co.in/"); const text = await driver.getText("//a[text()='Gmail']"); // 这里可以添加断言,比如用chai // expect(text).to.equal('Gmail'); console.log('Gmail文本:', text); }); after(async function() { await driver.end(); }); });
然后通过Mocha命令运行测试:
mocha add.js
总结
- 如果要复用WebdriverIO的操作逻辑,就封装成返回Promise的异步函数,不要嵌套Mocha测试块;
- 如果是写测试用例,就用Mocha的标准结构,通过测试命令运行,而不是试图从测试函数中获取返回值。
内容的提问来源于stack exchange,提问作者Banu Prashanth
相关产品推荐
相关产品推荐

