You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mocha中async/await使用问题:测试挂起或未处理Promise拒绝

解决Mocha中async/await测试Basic Auth 401时的挂起与未处理Promise拒绝问题

你的测试出现挂起或未处理Promise拒绝,主要是两个常见问题导致的:async函数与done回调混用,以及request-promise对非2xx状态码的默认处理逻辑,咱们一步步解决:

问题根源拆解

  1. async函数和done不能同时用
    Mocha对async函数的处理逻辑是自动等待其返回的Promise完成,不需要额外调用done。如果你的it回调既用了async,又声明了done参数,Mocha会一直等待你调用done,但async函数执行完后并不会触发done,最终导致测试超时挂起。

  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:28:36