Jest toThrow无法捕获Promise抛出的Error问题求助
问题分析与修正方案
你代码里的几个核心问题:
Promise内部异步回调的错误无法通过throw传递
Node.js的readLine回调是异步执行的,在这个回调里throw new Error()不会被Promise的捕获逻辑处理——因为回调的执行栈已经脱离了Promise的上下文,必须手动调用Promise的reject方法来传递错误。getUserValue函数存在语法错误
代码里括号不匹配,readLine的回调函数和Promise的回调都没正确闭合,这会直接导致代码运行报错。Jest测试方法不对
play是async函数,它返回的是Promise,同步的toThrow()无法捕获异步Promise的错误,必须用Jest专门处理异步错误的方式。
修正后的代码
1. 修复getUserValue和play函数
const readline = require('readline'); // 创建readline接口实例(Node.js readLine的正确用法) const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); function getUserValue(){ return new Promise((resolve, reject) => { rl.question("enter the number : ", (enter) => { if(enter.length > 3){ // 用reject传递错误,而非直接throw reject(new Error("some error")); } else { // 正常场景resolve结果 resolve(enter); } rl.close(); }); }); } async function play(){ try{ const value = await getUserValue(); console.log('输入的值:', value); } catch(err){ // catch捕获的是Error对象,直接取message输出 console.log(err.message); } }
2. 正确的Jest测试代码
// 模拟readline,避免测试时等待真实用户输入 jest.mock('readline', () => { const mockRl = { question: jest.fn(), close: jest.fn() }; return { createInterface: jest.fn(() => mockRl) }; }); const readline = require('readline'); const { play } = require('./your-file-path'); // 替换为你的实际文件路径 test("exception test", async () => { const rl = readline.createInterface(); // 模拟输入长度超3的场景,触发reject rl.question.mockImplementation((prompt, callback) => { callback('1234'); // 输入4位字符 }); // 用async/await配合rejects.toThrow捕获异步错误 await expect(play()).rejects.toThrow("some error"); });
关键说明
- 异步回调里的错误必须通过
reject传递给Promise,不能直接throw——回调的执行上下文不在Promise的try/catch范围内,throw的错误会变成未捕获异常。 - Jest测试异步Promise的错误时,必须用
await expect(...).rejects.toThrow(),或者使用.catch()配合done回调;同步的toThrow()只适用于同步函数的错误捕获。
内容的提问来源于stack exchange,提问作者sunub
相关产品推荐
相关产品推荐

