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

使用SuperTest测试Express应用时如何mock express-session会话?

解决方案

方案一:直接操作session store写入模拟会话(无额外依赖,推荐)

核心逻辑是手动向session存储中写入已登录的会话数据,再将对应签名后的session id传入请求cookie即可通过校验。

步骤1:调整session配置暴露store实例

修改你的setupSession方法,将session store实例挂载到可访问的位置:

setupSession(){
  const session = {
    secret: process.env.SESSION_SECRET,
    cookie: {},
    resave: false,
    saveUninitialized: false,
  };
  // 初始化store并挂载,方便测试时调用
  this.sessionStore = session.store || new expressSession.MemoryStore();
  session.store = this.sessionStore;
  this.app.use(expressSession(session));
}

步骤2:封装mock会话工具函数

实现方法生成已登录的会话和对应cookie:

const crypto = require('crypto');
const cookieSignature = require('cookie-signature');

async function generateMockLoginCookie(store, mockUser, sessionSecret) {
  // 生成随机session id
  const sessionId = crypto.randomBytes(16).toString('hex');
  // 构造和业务登录逻辑一致的session内容
  const sessionData = {
    cookie: {
      maxAge: 24 * 60 * 60 * 1000, // 与业务配置的cookie有效期保持一致
      httpOnly: true,
      secure: false
    },
    // 这里替换为你实际登录后写入session的字段
    user: mockUser,
    isLogin: true
  };
  // 写入session到存储
  await new Promise((resolve, reject) => {
    store.set(sessionId, sessionData, (err) => err ? reject(err) : resolve());
  });
  // 生成express-session要求的签名格式cookie
  const signedId = cookieSignature.sign(sessionId, sessionSecret);
  return `connect.sid=s%3A${signedId}`;
}
it("User should pass", async () => {
  // 生成mock登录态cookie
  const loginCookie = await generateMockLoginCookie(
    app.sessionStore,
    { id: 1, username: 'testUser' }, // 自定义mock用户数据
    process.env.SESSION_SECRET
  );
  // 请求携带cookie即可通过登录校验
  await supertest(app)
    .get("/user")
    .set('Cookie', [loginCookie])
    .expect(200);
});

方案二:通过supertest agent模拟真实登录(已有登录接口时更简便)

如果项目有现成的登录接口,可以用supertest内置的agent自动维护cookie,无需手动操作session store:

it("User should pass", (done) => {
  // 初始化agent实例,会自动保存接口返回的cookie
  const requestAgent = supertest.agent(app);
  // 先调用真实登录接口获取登录态
  requestAgent.post('/login')
    .send({ username: 'test', password: 'test123' })
    .expect(200)
    .end(() => {
      // 后续请求会自动携带登录cookie
      requestAgent.get('/user')
        .expect(200, done);
    });
});

注意事项

  • 测试环境的SESSION_SECRET必须和业务代码中的配置完全一致,否则session签名校验会失败
  • 如果业务配置了cookie的secure: true,测试环境需要关闭该配置,或者使用HTTPS协议发起测试请求
  • 多测试用例场景下,测试结束后可以调用store.destroy(sessionId)清理mock的会话数据,避免用例之间相互影响

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 00:27:03