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
相关产品推荐
相关产品推荐

