使用Jest+Nock模拟接口时,抛出错误的测试不通过求助
解决Jest异步错误断言不通过的问题
你的测试用例有几个关键问题导致无法通过,我来帮你一步步排查和修复:
1. 异步错误的断言方式错误
你直接用await getProject(...)然后expect(response).toThrowError是行不通的——因为当异步函数抛出错误时,await会直接把这个错误抛出,不会赋值给response变量,而且toThrowError是同步断言方法,不能直接用来断言异步抛出的错误。
正确的做法是使用Jest的rejects匹配器,或者用try/catch手动捕获错误:
方法一:使用rejects匹配器(推荐)
it('should throw error when record does not exists', async () => { const noExistsJSONFile = path.join(__dirname, "../../../data/api/project/non-existing.json"); nock(__ROOT_API__) .defaultReplyHeaders({ 'access-control-allow-origin': '*' }) .get('/projects/2500') .replyWithFile(404, noExistsJSONFile); // 直接断言异步函数调用会reject并抛出指定错误 await expect(getProject('/projects/2500')).rejects.toThrowError( `${notExisting.errorMessage} (Code: ${notExisting.errorCode})` ); });
方法二:用try/catch手动捕获
如果你需要更细致的错误检查,可以用这种方式:
it('should throw error when record does not exists', async() => { const noExistsJSONFile = path.join(__dirname, "../../../data/api/project/non-existing.json"); nock(__ROOT_API__) .defaultReplyHeaders({ 'access-control-allow-origin': '*' }) .get('/projects/2500') .replyWithFile(404, noExistsJSONFile); let caughtError; try { await getProject('/projects/2500'); } catch (err) { caughtError = err; } // 确保错误被正常捕获 expect(caughtError).toBeDefined(); // 断言错误信息符合预期 expect(caughtError.message).toBe(`${notExisting.errorMessage} (Code: ${notExisting.errorCode})`); });
2. 模板字符串语法错误
你原来的代码里expect(response).toThrowError(${notExisting.errorMessage} (Code: ${...`` 有两个问题:
- 模板字符串没有闭合(缺少结尾的
}和") ${...是无效的语法,应该替换成具体的错误代码变量,比如notExisting.errorCode
3. 额外检查点
除了上面的修复,你还需要验证以下几点:
- 确保
getProject函数确实会抛出错误:检查函数内部逻辑,当收到404响应时,是不是用throw new Error(...)抛出错误,而不是返回一个包含错误信息的对象。如果是返回错误对象,那你的断言逻辑就要改成检查返回值,而不是断言抛出错误。 - 验证nock拦截是否生效:可以在测试里添加
console.log(nock.isDone()),如果输出false,说明实际请求的URL和nock配置的不匹配(比如根URL__ROOT_API__是否带末尾斜杠、请求路径是否完全一致)。 - 避免nock跨测试污染:可以在测试前重置nock,防止其他测试的拦截影响当前测试:
beforeEach(() => { nock.cleanAll(); });
内容的提问来源于stack exchange,提问作者MarJano
相关产品推荐
相关产品推荐

