我使用express-session以最简单的方式存储登录信息:
req.session.userId = user.id
字符串
我将此配置用于一切都能完美工作的开发环境和规范:
app.use(express.json())
app.use(sessions({
secret: "secretthatwillbeputinenv",
saveUninitialized: true,
cookie: { maxAge: 1000 * 60 * 60 * 24 },
resave: false
}));
app.use(cookieParser());
app.use(express.urlencoded({ extended: true }));
app.use(cors())
app.use("/", router);
型
- 然而 * 当我使用supertest调用一个sign_in端点,然后调用另一个试图读取使用session持久化的信息的端点时,实际上没有任何信息。
req.session
正确地返回了一个session对象,但userId
是null。如何使express-session
在Jest中工作而不需要hacks和mocking任何东西?
2条答案
按热度按时间bbuxkriu1#
首先,我们应该知道
express-session
会将会话ID存储在cookie中,并通过会话ID在内存存储(默认存储)中查找会话数据。因此,我们需要保存会话ID cookie并在以下请求中使用它。supertest
包使用了superagent
,你不需要模仿任何东西。我们应该使用
superagent
提供的request.agent()
方法。来自Agents for global state文档:在Node中,SuperAgent默认情况下不保存Cookie,但您可以使用
.agent()
方法创建保存Cookie的SuperAgent副本request.agent()
将创建一个cookie jar示例(CookieJar
类来自cookiejar
包),当HTTP响应时,它将调用Agent.prototype._saveCookies()
方法将cookie保存到cookie jar示例中。字符串
之后,发送一个新的HTTP请求,超级代理将调用
Agent.prototype._attachCookies()
方法将cookie从cookie jar示例附加到请求。型
例如,在一个示例中,
File app.js:
型
File app.test.js:
型
测试结果:
型
mklgxw1f2#
您遇到此问题的原因是
supertest
为每个.get()
、.post()
等函数调用发出单独的HTTP请求,并且每个请求都是隔离的和无状态的。也就是说,它们之间不像真实的的Web浏览器那样共享Cookie或会话。supertest
提供了一种“链接”请求的方法,它可以保存cookie并维护会话。它涉及到创建一个agent
示例,您可以使用它来发出请求。您可以这样做:
字符串
request.agent(app)
会建立一个supertest
代理程式。这个代理程式会将Cookie附加到它所发出的要求,以便它可以在多个要求之间维持一个阶段作业。.post('/login')
呼叫会让使用者登入。因为这是使用代理程式进行的,所以会保留登入阶段作业。.get('/protected')
调用访问一个受保护的路由。因为这也是用agent
进行的,所以它使用由上一个登录调用创建的会话。该方法不需要任何hack或mock,并且应该允许express-session在Jest测试中正确工作,