使用Mocha+Chai测试MongoDB连接时超时问题求助
看起来你的问题出在测试块的上下文隔离和连接错误处理不完整上,让我一步步帮你分析和解决:
问题1:两个独立的describe块导致连接未复用
你写了两个分开的describe,第一个里面的before钩子只对它自己的测试生效,第二个describe运行时,MongoDB连接还没建立(甚至可能根本没触发连接逻辑),所以save操作一直等待连接,最终超时。而且第二个describe的after钩子执行时,mongoose.connection还没初始化,所以会出现Cannot read property 'dropDatabase' of undefined的错误。
问题2:连接错误未正确传递给Mocha
你的before钩子中,只监听了error事件并打印,但没有调用done.fail()来终止测试。如果MongoDB连接失败(比如服务没启动、地址不对),Mocha会一直等待done()被调用,直到超时。
修复方案
把连接逻辑和测试逻辑放在同一个父describe下,确保所有测试共享同一个连接上下文,同时完善错误处理:
'use strict'; const mongoose = require('mongoose'); const Schema = mongoose.Schema; const chai = require('chai'); const expect = chai.expect; // 定义Schema和Model const testSchema = new Schema({ firstname : {type: String,required:true}, lastname : {type: String, required:true}, id : {type : Number, required : true} }); const employee_details = mongoose.model('employee_details',testSchema); // 用一个父describe包裹所有测试,共享连接上下文 describe('MongoDB Collection Tests', () => { // 在所有测试前建立连接 before((done)=>{ mongoose.connect('mongodb://127.0.0.1:27017/new_demo') .then(() => { console.log('Connected to new_demo db'); done(); }) .catch(err => { console.error('Error connecting to DB:', err); done.fail(err); // 连接失败时通知Mocha终止测试 }); }); describe('Test Database function',()=>{ it('saves a new record',(done)=>{ var first_record = employee_details({ firstname : 'Mike', lastname : 'Stevens', id : 19981 }); first_record.save((err) => { if (err) done.fail(err); else done(); }); }); }); // 在所有测试后清理数据库并关闭连接 after((done)=>{ mongoose.connection.db.dropDatabase() .then(() => mongoose.connection.close(done)) .catch(err => { console.error('Error cleaning up:', err); done.fail(err); }); }); });
额外优化建议
- 推荐使用
async/await代替回调,让代码更简洁易读:
before(async () => { try { await mongoose.connect('mongodb://127.0.0.1:27017/new_demo', { useNewUrlParser: true, useUnifiedTopology: true // 避免Mongoose 5.x+的过时警告 }); console.log('Connected to new_demo db'); } catch (err) { console.error('Error connecting to DB:', err); throw err; // 抛出错误让Mocha捕获 } }); it('saves a new record', async () => { const first_record = new employee_details({ firstname : 'Mike', lastname : 'Stevens', id : 19981 }); await first_record.save(); // 可以加断言验证保存结果,让测试更严谨 expect(first_record._id).to.exist; }); after(async () => { try { await mongoose.connection.db.dropDatabase(); await mongoose.connection.close(); } catch (err) { console.error('Error cleaning up:', err); throw err; } });
- 确保MongoDB服务确实在运行(通过
mongod命令启动),并且端口是默认的27017 - 如果你的Mongoose版本较新,连接时加上
useNewUrlParser: true, useUnifiedTopology: true参数,避免过时的连接警告
内容的提问来源于stack exchange,提问作者demouser123
相关产品推荐
相关产品推荐

