You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 14:06:03