Jest测试用例中如何正确处理Promise reject及resolves断言报错问题
问题根因总览
所有报错都来自两个核心错误:
.resolves/.rejects只能作用于未resolve的Promise对象,你要么提前await了Promise导致拿到的是普通对象,要么没有正确处理断言返回的Promise- supertest返回的
response是完整的HTTP响应对象,包含header、status、body等字段,你不能直接把它和db返回的业务数据做匹配
修复方案
1. 错误场景(check Bad Pool)修复
你这里已经用了await request(app).get(),response已经是请求完成后的响应对象,根本不是Promise,所以调用.rejects必然报错。正确写法有两种可选:
写法一:直接断言已返回的响应内容(推荐,逻辑更直观)
it('check Bad Pool', async () => { executeDb2Query.mockImplementation(() => Promise.reject(new Error('Unable to connect to db2')) ) const response = await request(app).get( '/api/v1/abc/xyz/123456' ) // 直接断言响应内容和状态,不需要用rejects expect(response.body.msg).toEqual('Unable to connect to db2') expect(response.status).toEqual(500) })
写法二:如果一定要用.rejects,就不要提前await请求
it('check Bad Pool', async () => { executeDb2Query.mockImplementation(() => Promise.reject(new Error('Unable to connect to db2')) ) // 不await,保留request返回的Promise对象 const requestPromise = request(app).get('/api/v1/abc/xyz/123456') // 要await这个断言的Promise,不然会出现未处理rejection警告 await expect(requestPromise).rejects.toThrow('Unable to connect to db2') })
2. 成功场景(check Good Pool)修复
这里有两个错误:一是没加async/await,二是你把HTTP响应对象直接和db返回的业务数组做匹配了,实际业务数据存在response.body里。修复后的代码:
it('check Good Pool', async () => { executeDb2Query.mockImplementation(() => Promise.resolve([ { isAvailable: true } ]) ) // 加await拿到响应对象 const response = await request(app).get('/api/v1/abc/xyz/090703') // 断言body的内容,而不是直接断言response expect(response.body).toStrictEqual([ { isAvailable: true } ]) // 可以额外加状态码断言确保正常 expect(response.status).toEqual(200) })
如果你一定要用.resolves写法,也可以写成:
it('check Good Pool', async () => { executeDb2Query.mockImplementation(() => Promise.resolve([ { isAvailable: true } ]) ) const requestPromise = request(app).get('/api/v1/abc/xyz/090703') // 要await断言的Promise,同时取body字段匹配 await expect(requestPromise.then(res => res.body)).resolves.toStrictEqual([ { isAvailable: true } ]) })
未处理Promise Rejection警告的原因
这个警告是因为你没有await带.resolves/.rejects的断言语句,断言本身返回的是Promise,如果失败就会抛出未被捕获的rejection。只要给所有.resolves/.rejects的断言前加上await就能解决。
内容的提问来源于stack exchange,提问作者QuickLearner
相关产品推荐
相关产品推荐

