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

Jest测试报错req.session.save is not a function如何mock该方法

问题原因

使用httpMocks.createRequest()生成的模拟请求对象,默认不会自动注入express-session中间件挂载的session属性,自然也不存在异步方法save(),因此执行到await req.session.save()时会抛出req.session.save is not a function错误。
另外原测试代码还有两个隐性问题:

  • describe拼写错误,写成了descibe
  • 调用async类型的controller方法时没有加await等待异步逻辑执行完成,断言会在业务逻辑跑完前触发,大概率得到不符合预期的结果。
修复方案

在初始化模拟请求对象后,手动挂载mock的session对象,将save方法实现为返回Promise的jest mock函数即可,同时修正异步调用和拼写问题。
修正后的测试代码如下:

describe('test',()=> {
    let req: any;
    let res: any;

    beforeEach(() => {
        // 每个用例执行前重新生成mock对象,避免用例间状态污染
        req = httpMocks.createRequest();
        res = httpMocks.createResponse();
        
        // 挂载mock的session实现
        req.session = {
            save: jest.fn().mockResolvedValue(undefined)
        };
    });

    it('should connected', async () => {
        // 等待异步controller执行完成
        await myController.connect(req, res);

        expect(res.statusCode).toBe(200);
        // 可选:断言session.save被正确调用
        expect(req.session.save).toHaveBeenCalledTimes(1);
        // 可选:断言session内写入的token符合预期
        expect(req.session.testToken).toEqual({
            refresh_token: expect.any(String),
            access_token: expect.any(String),
            expires_in: 1200
        });
        expect(res._isEndCalled()).toBeTruthy();
        expect(res._getJSONData()).toEqual({success:true, message:'Connected'});
    });
})
注意事项
  • req.session.save是异步方法,mock时必须返回Promise,推荐直接用jest.fn().mockResolvedValue(undefined)模拟成功场景,如果要测试save失败的分支,可以在用例内单独用mockRejectedValue模拟抛出错误的情况。
  • 涉及异步逻辑的测试用例必须加async/await等待逻辑执行完毕,否则断言时机不对会出现偶现失败的问题。
  • 把mock初始化逻辑放到beforeEach中,可以保证每个用例拿到的都是全新的mock对象,避免上一个用例修改session内容、记录save调用次数导致下一个用例断言失败。

内容的提问来源于stack exchange,提问作者Shivam Sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 15:12:21