使用Mocha发起API请求返回undefined响应的问题求助
排查思路与修复方案
你遇到的响应undefined问题,90%以上是异步测试未正确处理导致的,按以下优先级排查:
- 第一优先级:补全Mocha异步测试的等待逻辑
Mocha执行测试用例时,如果没有显式告知用例包含异步逻辑,会在所有同步代码执行完毕后直接结束用例,不会等待supertest的HTTP请求返回。你当前写的代码里,request.get().end()是非阻塞的异步调用,回调函数还没触发、响应还没返回的时候,Mocha已经把用例跑完了,此时回调里拿到的上下文未就绪,就会出现undefined。
两种标准修复写法:
- 使用done回调模式,给it块的测试函数传入done参数,在请求回调处理完成后调用done通知Mocha用例结束,同时优先处理请求错误,避免报错时res为空:
import supertest from "supertest"; import { expect } from 'chai'; const request = supertest("https://api.staging.graana.rocks/api/"); let a; describe('Users', () => { it('GET /users', (done) => { request.get('city?home=true').end((err, res) => { // 先抛出请求错误,避免错误场景下res为undefined if (err) return done(err); expect(res.body.data).to.not.be.null; a = res.body.data; console.log(res.body.data); console.log(a); done(); }); }); });
- 使用async/await模式,supertest原生支持Promise返回,Mocha会自动等待async函数执行完毕,写法更简洁:
import supertest from "supertest"; import { expect } from 'chai'; const request = supertest("https://api.staging.graana.rocks/api/"); let a; describe('Users', () => { it('GET /users', async () => { const res = await request.get('city?home=true'); expect(res.body.data).to.not.be.null; a = res.body.data; console.log(res.body.data); console.log(a); }); });
- 第二优先级:校验请求路径与响应格式
- 检查接口路径是否正确:你当前用例描述是
GET /users,但实际请求的路径是city?home=true,和baseURL拼接后的完整地址是https://api.staging.graana.rocks/api/city?home=true,如果路径写错返回404/401/500等错误,且未做错误捕获时,直接访问res属性很容易拿到undefined。 - 先打印完整响应排查结构:不要直接取
res.body.data,先打印res.status、res.headers、res.text确认:- 接口是否返回200状态码
- 响应头的
content-type是否为application/json,如果接口返回的是HTML、纯文本,supertest不会自动将响应解析为JSON对象,此时res.body为空,取data自然是undefined - 响应的JSON结构中是否真的存在
data字段,部分接口在业务报错时会返回{code: 错误码, message: 错误信息}结构,不存在data字段
- 第三优先级:排查依赖兼容问题
如果以上逻辑都修正后仍有问题,删除本地node_modules目录和锁文件(package-lock.json/yarn.lock/pnpm-lock.yaml),重新安装依赖,排除supertest、mocha、chai大版本不兼容导致的响应解析异常。
内容的提问来源于stack exchange,提问作者Wajih Haider
相关产品推荐
相关产品推荐

