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

Jest回调函数中expect断言失败但测试仍显示通过的问题

解决Jest回调内断言失败但测试仍标记为通过的问题

问题核心是异步回调的执行时机:你的测试函数虽标记为async,但User.createLocal是基于回调的异步操作,Jest会在同步代码执行完毕(即调用完createLocal后)就判定测试完成,此时回调还未执行。后续回调内的断言失败时,测试状态已经被标记为通过,无法再更新。

下面是三种可行的解决方法:

方案一:用Promise包裹回调,配合async/await

将回调式操作包裹进Promise,通过await让Jest等待异步操作完成,同时捕获断言错误:

test('Create local user test@example.com', async () => {
  await new Promise((resolve, reject) => {
    User.createLocal({ email: "test@example.com" }, (err, usr, options) => {
      try {
        expect(err).toBeNull();
        expect(options).toBeNull();
        expect(usr).not.toBeNull();
        resolve(); // 所有断言通过后标记Promise完成
      } catch (e) {
        reject(e); // 断言失败时抛出错误,让Jest捕获
      }
    });
  });
});

方案二:使用Jest的done回调

Jest支持给测试函数传入done参数,用于标记异步测试的完成。断言失败时的错误会被Jest自动捕获,也可以手动用try/catch包裹并传递错误:

test('Create local user test@example.com', (done) => {
  User.createLocal({ email: "test@example.com" }, (err, usr, options) => {
    try {
      expect(err).toBeNull();
      expect(options).toBeNull();
      expect(usr).not.toBeNull();
      done(); // 断言全部通过后调用done
    } catch (e) {
      done(e); // 手动传递错误,确保Jest标记测试失败
    }
  });
});

方案三:将回调式API转为Promise版本

如果你的库支持Promise,或者可以用Node.js的util.promisify转换回调函数,就能直接用async/await简化测试:

const { promisify } = require('util');
// 把回调式的createLocal转为Promise版本
const createLocalPromise = promisify(User.createLocal);

test('Create local user test@example.com', async () => {
  const [err, usr, options] = await createLocalPromise({ email: "test@example.com" });
  expect(err).toBeNull();
  expect(options).toBeNull();
  expect(usr).not.toBeNull();
});

内容的提问来源于stack exchange,提问作者user9128309

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 05:31:18