使用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}`; }
步骤3:调整测试用例使用mock cookie
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
相关产品推荐
相关产品推荐

