使用Jest测试异步函数抛错时出现'function did not throw'问题
问题:Jest测试异步函数无法捕获预期错误
我的业务代码:
export class UnexpectedRequestError { constructor(public message: string = 'Unauthorized') { this.message = message; } } export const foo = async (arg: boolean) => { if (arg) { return true; } else { const message = 'message'; await sendSlackMessage(message); throw new UnexpectedRequestError(message); } };
测试代码:
test('throws UnexpectedRequestError', async () => { await expect(foo(false)).rejects.toThrow(UnexpectedRequestError); });
测试返回的错误信息:
expect(received).rejects.toThrow(expected) Expected constructor: UnexpectedRequestError Received function did not throw
我在Stack Overflow搜索过类似问题,没发现代码存在问题,请问哪里出错了?
问题原因及解决方法
核心问题1:未模拟sendSlackMessage函数
你调用的sendSlackMessage是真实的异步函数,在测试环境中它可能抛出未被捕获的错误,或者无法正常resolve,导致后续的throw语句根本没机会执行,Jest自然检测不到预期的错误。
解决: 在测试文件中模拟这个函数,让它正常resolve:
// 假设sendSlackMessage从'./slack'模块导出 jest.mock('./slack', () => ({ sendSlackMessage: jest.fn().mockResolvedValue(undefined) })); // 如果是全局函数,直接定义模拟 global.sendSlackMessage = jest.fn().mockResolvedValue(undefined);
核心问题2:自定义错误类未继承Error
你的UnexpectedRequestError没有继承原生Error类,Jest的toThrow在进行类型校验时会出现识别问题,因为它默认只识别标准Error子类的实例。
解决: 修改错误类继承Error:
export class UnexpectedRequestError extends Error { constructor(public message: string = 'Unauthorized') { super(message); this.name = 'UnexpectedRequestError'; // 可选,设置错误名称方便调试 } }
可选:用try/catch方式验证错误
如果还是有问题,可以改用try/catch捕获错误,这样能更直观地排查中间是否有其他错误:
test('throws UnexpectedRequestError', async () => { expect.assertions(2); // 确保下面两个expect都会执行 try { await foo(false); } catch (error) { expect(error).toBeInstanceOf(UnexpectedRequestError); expect(error.message).toBe('message'); } });
内容的提问来源于stack exchange,提问作者ta539tg70
相关产品推荐
相关产品推荐

