Node.js Mocha数据库连接测试本地通过但Jenkins执行失败问题排查
Jenkins上Mocha数据库连接测试失败的原因及解决办法
问题背景
你在本地用Mocha测试数据库错误凭证的场景时测试通过,但在Jenkins上运行时失败,报错:
Access to DB #fail should return -1 because wrong credentials: [0m[31m Error: connect ECONNREFUSED 127.0.0.1:3306[0m[90m
at TCPConnectWrap.afterConnect [as oncomplete]
测试代码如下:
describe('Access to DB', function(){ describe('#fail', function(){ it('should return -1 because wrong credentials', function(done){ var connection = mysql.createConnection({ host: 'localhost', user: 'root', password: 'head', database: 'head' }); connection.connect(done); }); }) });
Jenkins部署在独立服务器(未安装MySQL),Node应用在另一台服务器,其他功能正常。你想知道是不是Jenkins没装MySQL导致的失败。
答案:是的,这就是测试失败的核心原因
你的测试代码里指定的数据库host是localhost,也就是执行测试的机器:
- 本地运行时,你的电脑上安装并运行了MySQL服务,所以即使凭证错误,连接请求能到达MySQL服务,服务会返回“凭证错误”的响应,这时候
connect(done)会把这个错误传给测试框架,符合你预期的“失败场景”。 - 但在Jenkins服务器上,没有安装MySQL服务,也就没有程序监听3306端口。当测试尝试连接
localhost:3306时,系统直接返回ECONNREFUSED(连接被拒绝),这和你预期的“凭证错误”不是同一个错误,所以测试判定失败。
几个可行的解决方案
1. 连接到实际的测试数据库
把测试代码里的host改成你的Node应用所在服务器的MySQL地址(确保Jenkins服务器能访问该服务器的3306端口),这样测试就能连接到真实的MySQL服务,验证错误凭证的场景:
var connection = mysql.createConnection({ host: '你的Node应用服务器IP或域名', // 替换成实际地址 user: 'root', password: 'head', database: 'head' });
2. 使用测试替身模拟数据库行为
为了让测试不依赖真实数据库,你可以用Mock库模拟MySQL的连接逻辑,比如mysql-mock或者sinon:
- 模拟
mysql.createConnection返回的对象,让connect方法直接抛出“凭证错误”的异常,这样不管有没有真实数据库,测试都能按预期执行。 - 这种方式更适合CI环境,测试速度更快,也不会受外部服务影响。
3. 跳过CI环境的该测试(不推荐)
如果暂时不想修改测试,可以在Jenkins运行Mocha时,通过--grep参数跳过这个测试:
./node_modules/.bin/mocha ./test/test.js --grep "should return -1 because wrong credentials" --invert
不过这只是临时方案,建议尽量让测试能在CI环境运行,保证代码质量。
内容的提问来源于stack exchange,提问作者Duck_dragon
相关产品推荐
相关产品推荐

