Mocha中async/await使用问题:测试挂起或未处理Promise拒绝
解决Mocha中async/await测试Basic Auth 401时的挂起与未处理Promise拒绝问题
你的测试出现挂起或未处理Promise拒绝,主要是两个常见问题导致的:async函数与done回调混用,以及request-promise对非2xx状态码的默认处理逻辑,咱们一步步解决:
问题根源拆解
async函数和done不能同时用
Mocha对async函数的处理逻辑是自动等待其返回的Promise完成,不需要额外调用done。如果你的it回调既用了async,又声明了done参数,Mocha会一直等待你调用done,但async函数执行完后并不会触发done,最终导致测试超时挂起。request-promise默认抛出非2xx状态码
当服务器返回401这类非2xx状态码时,request-promise会把这个响应转为Promise拒绝。如果没有捕获这个拒绝,就会出现"未处理的Promise拒绝"错误。
修正后的测试代码方案
方案一:用try/catch捕获拒绝(推荐,更直观)
移除done参数,用try/catch包裹请求,在catch块中断言401状态:
const request = require('request-promise'); const expect = require('chai').expect; const basicToken = require('basic-auth-token'); describe('PUT Endpoint', function () { it.only('should return unauthorized if basic token is incorrect', async function () { // 生成无效的Basic Auth令牌 const invalidToken = basicToken('wrong-user', 'wrong-pass'); const options = { url: `http://url_to_handle_request`, method: 'PUT', // 别忘了指定PUT请求方法 resolveWithFullResponse: true, headers: { 'Authorization': `Basic ${invalidToken}` } }; try { // 发送请求,预期会因401被拒绝 await request(options); // 如果走到这里,说明请求意外成功,主动标记测试失败 expect.fail('Expected request to be rejected with 401 Unauthorized'); } catch (error) { // 捕获拒绝,断言状态码符合预期 expect(error.statusCode).to.equal(401); } }); });
方案二:禁用request-promise的非2xx拒绝逻辑
给options添加simple: false,让request-promise直接返回非2xx的响应,无需捕获异常:
const request = require('request-promise'); const expect = require('chai').expect; const basicToken = require('basic-auth-token'); describe('PUT Endpoint', function () { it.only('should return unauthorized if basic token is incorrect', async function () { const invalidToken = basicToken('wrong-user', 'wrong-pass'); const options = { url: `http://url_to_handle_request`, method: 'PUT', resolveWithFullResponse: true, simple: false, // 关键:不把非2xx状态转为Promise拒绝 headers: { 'Authorization': `Basic ${invalidToken}` } }; // 直接获取响应,断言状态码 const response = await request(options); expect(response.statusCode).to.equal(401); }); });
额外注意事项
- 确保你的请求options里指定了
method: 'PUT',否则request-promise默认会发GET请求,可能不符合你的测试场景。 - 如果你的
basicToken生成逻辑有问题,也可能导致测试异常,可以先单独打印invalidToken确认格式是否正确(应该是Base64编码的username:password字符串)。
内容的提问来源于stack exchange,提问作者user2151486
相关产品推荐
相关产品推荐

