Jest测试Promise.all拒绝场景时遇undefined问题的解决方法
问题分析与解决方案
你的问题核心出在mock方式不正确或者目标函数内部吞掉了Promise的拒绝状态,导致funcToTest没有按预期抛出拒绝。以下是具体解决步骤:
1. 确认funcToTest的逻辑正确性
首先检查funcToTest是否在内部捕获了Promise.all的错误却没有重新抛出——这会导致函数从拒绝状态变为resolved状态,返回undefined(也就是你看到的received为undefined的原因)。
错误的函数写法(吞掉错误)
async function funcToTest() { try { const [list1, list2, list3] = await Promise.all([ module1.getList1(), module2.getList2(), module3.getList3() ]); return { list1, list2, list3 }; } catch (err) { // 仅打印错误但不重新抛出,导致函数返回resolved的undefined console.error(err); } }
正确的函数写法(传递拒绝状态)
如果需要处理404异常,仅保留该逻辑,其他错误重新抛出:
async function funcToTest() { try { const [list1, list2, list3] = await Promise.all([ module1.getList1(), module2.getList2(), module3.getList3() ]); return { list1, list2, list3 }; } catch (err) { // 仅忽略404错误,其他错误重新抛出 if (err.status !== 404) { throw err; } return { list1: [], list2, list3 }; } }
如果不需要额外处理,直接去掉try/catch,让Promise.all的拒绝状态自然传递:
async function funcToTest() { const [list1, list2, list3] = await Promise.all([ module1.getList1(), module2.getList2(), module3.getList3() ]); return { list1, list2, list3 }; }
2. 正确Mock module1.getList1
必须确保mock的函数返回rejected状态的Promise,而不是同步抛出异常或返回resolved Promise。Jest提供了两种可靠方式:
方式1:使用mockRejectedValue(推荐)
// 全局mock module1 jest.mock('./module1', () => ({ getList1: jest.fn().mockRejectedValue(new Error('非404异常')) }));
方式2:用async函数模拟抛异常
因为async函数内部抛出异常时,会自动返回rejected状态的Promise:
jest.mock('./module1', () => ({ getList1: jest.fn().mockImplementation(async () => { throw new Error('非404异常'); }) }));
3. 正确断言拒绝状态
使用Jest的rejects匹配器,或try/catch手动捕获错误进行断言:
方式1:用expect().rejects.toThrow()
test('当getList1抛出非404异常时,funcToTest应该拒绝', async () => { // 可以在测试内动态修改mock的错误信息 const testError = new Error('测试用非404异常'); require('./module1').getList1.mockRejectedValue(testError); // 断言函数拒绝并匹配错误 await expect(funcToTest()).rejects.toThrow(testError); // 或匹配错误文本 await expect(funcToTest()).rejects.toThrow('测试用非404异常'); });
方式2:try/catch捕获断言
test('当getList1失败时,funcToTest拒绝', async () => { const testError = new Error('测试用非404异常'); require('./module1').getList1.mockRejectedValue(testError); let caughtError; try { await funcToTest(); } catch (err) { caughtError = err; } // 断言错误被捕获,且符合预期 expect(caughtError).toBeDefined(); expect(caughtError.message).toBe('测试用非404异常'); });
4. 排查Promise.allSettled显示全fulfilled的问题
如果用Promise.allSettled测试时所有Promise都显示fulfilled,说明你的getList1 mock实际上返回了resolved状态的Promise。检查mock代码:
- 避免使用
mockResolvedValue或错误地返回普通值 - 确保mock的是异步函数的拒绝状态,而非同步抛出异常(同步异常会被Promise包装为rejected,但如果mock写法错误可能导致意外)
内容的提问来源于stack exchange,提问作者Ridhwaan Shakeel
相关产品推荐
相关产品推荐

