Node.js:如何在测试脚本中关闭tunnel-ssh创建的SSH连接
为什么测试里的SSH连接关闭不生效?
这个问题的核心是异步操作的时序问题:tunnel-ssh的连接建立是异步的,你当前的sshConnection函数会立刻返回server变量,但此时tunnel的回调还没执行,server其实还没被正确初始化完成——说白了,你调用server.close()的时候,这个server对象根本还没真正代表一个已建立的SSH连接,所以自然不会有任何效果。而你在原脚本回调里调用server.close()能生效,是因为那时候回调已经触发,server已经是一个有效连接实例了。
解决方法:用Promise封装异步连接过程
我们需要把sshConnection改成异步函数,通过Promise等待连接真正建立完成后,再返回可用的server实例。这样测试代码就能确保拿到的是已经初始化好的连接对象,调用close()也就会生效了。
第一步:修改connection.js中的函数
const tunnel = require('tunnel-ssh'); const MongoClient = require('mongodb').MongoClient; function sshConnection() { return new Promise((resolve, reject) => { const config = { /* 你的SSH配置参数 */ }; tunnel(config, (error, server) => { if (error) { console.log("SSH connection error: " + error); reject(error); } else { console.log('ssh connection done'); resolve(server); } }); }); } // 顺便把MongoDB连接也改成Promise风格,让测试更可靠 function mongoConnection() { const uri = "mongodb://localhost:27018/"; const client = new MongoClient(uri, { useNewUrlParser: true }); return client.connect() .then(() => { console.log('mongodb connection done'); return client; }) .catch(err => { console.error('MongoDB connection error:', err); throw err; }); } module.exports = { sshConnection, mongoConnection };
第二步:修改测试文件connection_test.js,使用async/await等待连接
const connection = require('../utilities/connection'); describe('testing the mongodb connection', function() { it('establishes and closes an ssh connection', async function() { try { // 等待SSH连接真正建立完成 const server = await connection.sshConnection(); // 现在调用close就会生效了 server.close(); console.log('SSH connection closed successfully'); } catch (err) { console.error('SSH test failed:', err); throw err; // 确保测试标记为失败 } }); it('establishes and closes a mongodb connection', async function() { try { // 等待MongoDB连接完成 const client = await connection.mongoConnection(); client.close(); console.log('MongoDB connection closed successfully'); } catch (err) { console.error('MongoDB test failed:', err); throw err; } }); });
为什么这样改能解决问题?
通过Promise封装异步操作,我们强制测试代码等待连接建立的异步过程完成,确保拿到的server和client都是已经成功初始化的实例。这时候再调用close(),就能正确触发连接关闭的逻辑了。
内容的提问来源于stack exchange,提问作者christos.goulas
相关产品推荐
相关产品推荐

