如何使用Chai断言库的spies完成登录功能测试并排查返回值异常问题
问题原因
你测试结果始终返回true的核心问题是测试代码里的Spy配置完全覆盖了真实的login方法逻辑,具体问题如下:
- 你调用
chai.spy.on(apiController, 'login', () => true)时,第三个参数是自定义的Mock实现,这会让apiController.login完全不再执行你写的真实登录校验逻辑,不管传入什么参数都会直接返回固定值true,和你传入的登录凭证是否正确没有任何关系。 - 真实的
login方法要求传入request、response两个参数,你的测试代码只传入了一个loginUserDetails,就算不做Mock,真实逻辑运行时也会出现参数读取错误。 - 真实
login方法返回的是包含响应状态码、响应体的结构,你的断言判断返回值等于200,和Mock返回的true本身也无法匹配。
修复方案
根据你的测试目的可以选择两种修改方式:
1. 测试真实login逻辑
不要Mocklogin方法本身,只Mock其内部调用的第三方请求库req,避免发送真实网络请求即可,示例代码如下:
const req = require('你的项目中req依赖对应的引入路径'); describe('API Endpoints tests', () => { beforeEach(() => { chai.spy.restore(); }); describe('/POST login', () => { it('正确凭证下登录成功返回200', async () => { // 只Mock内部的req请求 chai.spy.on(req, (opts, callback) => { // 根据传入的凭证返回对应响应 if (opts.json.email === 'test@example.com' && opts.json.password === 'correct_pass') { return callback(null, { statusCode: 200 }, { token: 'test_token', user: { roles: ['admin'] } // 匹配你配置的AUTHORIZED_ROLES }); } // 错误凭证返回403 return callback(null, { statusCode: 403 }, {}); }); // 构造符合要求的入参 const mockReq = { body: { email: 'test@example.com', password: 'correct_pass', staging: false } }; const mockRes = {}; // 直接调用真实login方法 const result = await apiController.login(mockReq, mockRes); // 按实际返回结构断言,这里假设你最终return的是statusCode chai.assert.equal(result.statusCode, 200); }); }); });
2. 仅测试login方法的调用逻辑
如果你不需要校验login内部逻辑,仅要验证上层代码是否正确调用了login,可以保留Spy但根据入参动态返回值:
chai.spy.on(apiController, 'login', (req) => { // 根据传入的凭证动态返回结果 if(req.body.email === '正确邮箱' && req.body.password === '正确密码') { return 200; } return 401; });
如果是测试完整接口的运行情况,更建议使用supertest直接模拟HTTP请求调用接口,不需要单独调用Controller方法。
内容的提问来源于stack exchange,提问作者user8107351
相关产品推荐
相关产品推荐

