使用Mocha提取接口响应access_token并传入后续请求头的问题
问题解决办法
1. 提取access_token的问题
你现有代码的错误点:
- 回调参数顺序错误:chai-http的
.end()回调第一个参数是错误对象err,第二个才是响应对象res,参数顺序写反会导致拿不到正确的响应内容 - 取值逻辑错误:
JSON.stringify.access_token是完全错误的写法,JSON.stringify是序列化方法,不是响应数据对象。从你贴的响应结构来看,access_token存放在text字段的JSON字符串里,如果chai没有自动解析成res.body,可以手动解析res.text
正确的提取写法:
.end(function(err, res) { if (err) return console.error(err); expect(res).to.have.status(200); // 两种取值方式二选一 // 方式1:如果chai已经自动解析响应为res.body const token = res.body.access_token; // 方式2:如果res.body为空,手动解析text字段 // const token = JSON.parse(res.text).access_token; console.log('提取到的token:', token); done(); })
2. 后续请求传token报undefined的问题
这是变量作用域和测试执行顺序的问题:
- 你在第一个请求的回调里定义的
eurotoken是局部变量,和第二个it块里声明的eurotoken完全是两个变量,后者从来没有被赋值,自然是undefined - 你把获取token的逻辑和业务请求逻辑写在了两个独立的测试用例里,执行顺序不能保证先拿到token再执行业务请求
正确的写法:
把token变量提到外层作用域,用before钩子先完成token获取,再执行后续测试用例:
// 外层作用域声明token变量 let eurotoken; // 所有测试用例执行前先获取token before((done) => { chai.request(uaaUrl) .post('/oauth/token') .set('Content-Type', 'application/x-www-form-urlencoded') .set('Accept', '*/*') .send(Authuser) .end(function(err, res) { if (err) return done(err); // 这里直接赋值即可,不需要多余的JSON.parse+JSON.stringify操作 eurotoken = res.body.access_token; console.log('parsedd token', eurotoken); expect(res).to.have.status(200) done(); }) }) it('./health', (done) => { chai.request(euro_url) .get('/request-statuses') .set('Content-Type', 'application/x-www-form-urlencoded') .set('Accept', '*/*') // 直接使用外层已经赋值的eurotoken .set('Authorization', `Bearer ${eurotoken}`) .end(function(err, res) { if (err) return done(err); expect(res).to.have.status(200) done(); }) });
其他需要修正的细节
- 多余操作:
JSON.parse(JSON.stringify(res.body.access_token))完全没有必要,access_token本身就是字符串,直接取值即可 - 第二个请求的
.end()回调你也写反了res和err的顺序,会导致错误捕获异常 - 第二个请求的回调里
if/else分支已经调用了done(),分支外的done()需要删掉,否则会触发重复调用报错
内容的提问来源于stack exchange,提问作者Triin86
相关产品推荐
相关产品推荐

