使用Chai和Mocha做单元测试:POST请求前登录授权的问题
问题分析与解决方案
我一眼就看出问题所在啦——你没正确保留登录后的会话状态!
你在before块里用chai.request.agent(app)发起了登录请求,但这个带会话的请求实例没有被保存下来。到了it测试块里,你又用chai.request(app)新建了一个完全独立的请求对象,这个新对象根本不知道之前的登录操作,自然会以未授权的身份发起请求。
修复步骤
- 在
describe块的作用域内声明一个变量,用来持久化保存登录后的agent实例 - 在
before块中,把chai.request.agent(app)的返回值赋值给这个变量,完成登录后,这个agent就会自动保存会话Cookie - 在
it测试块中,使用这个保存好的agent来发起POST请求,而不是重新创建新的请求对象
修改后的完整代码
describe('/POST _json post data as a admin', () => { // 声明变量保存带会话的agent实例 let agent; before((done) => { const loginInfo = { usr: 'testuser', psw: 'mochatesting197' }; // 初始化agent并保存到变量中 agent = chai.request.agent(app); agent .post('/login') .send(loginInfo) .then((res) => { // 这里可以加个断言,确保登录确实成功了,比如检查状态码或返回内容 res.should.have.status(200); done(); }) .catch((err) => done(err)); // 别忘了捕获登录失败的错误,避免测试卡死 }); it('POST data as a admin', (done) => { const json = { module_name: "TEST ENTRY", module_url: "/TEST_ENTRY", module_privilege: "testentry;testentry2;testentry3" }; // 使用保存好的agent发起请求,会话状态会自动带上 agent .post('/_json') .send(json) .then((res) => { res.should.have.status(200); res.body.should.be.a('object'); res.body['success'].should.have.property('message'); done(); }) .catch((err) => done(err)); }); });
额外优化建议
- 可以把
done换成async/await,让异步代码更简洁易读:
describe('/POST _json post data as a admin', () => { let agent; before(async () => { const loginInfo = { usr: 'testuser', psw: 'mochatesting197' }; agent = chai.request.agent(app); const res = await agent.post('/login').send(loginInfo); res.should.have.status(200); }); it('POST data as a admin', async () => { const json = { module_name: "TEST ENTRY", module_url: "/TEST_ENTRY", module_privilege: "testentry;testentry2;testentry3" }; const res = await agent.post('/_json').send(json); res.should.have.status(200); res.body.should.be.a('object'); res.body['success'].should.have.property('message'); }); });
- 一定要在
before块里验证登录请求的结果,避免因为登录失败导致后续测试无意义地失败。
内容的提问来源于stack exchange,提问作者NashPL
相关产品推荐
相关产品推荐

