在Jest中如何获取supertest请求返回Cookie中的JWT令牌?
方案1:直接从响应体提取(最简便)
你的接口已经主动把accessToken和refreshToken放在响应体返回了,直接读取即可。如果要在其他测试用例复用令牌,把变量定义在describe作用域下就行:
import server from "../server" import supertest from "supertest" import mongoose from "mongoose" import dotenv from "dotenv" dotenv.config() const request = supertest(server) describe("Testing Auth endpoints", () => { // 定义在顶层作用域,所有测试用例都可以访问 let accessToken: string let refreshToken: string let cookies: string[] beforeAll(done => { const PORT = process.env.PORT mongoose .connect(process.env.MONGO_STRING_TEST!) .then(() => { console.log("Connect to Atlas. Test DB.") done() }) .catch(err => console.log(err)) }) const validUser = { name: "Paul Stevens", email: "ps@g.com", password: "1234", role: "host", } it("should test /register for a valid request and return 201 status code and accessToken and refreshToken through cookies", async () => { const resp = await request.post("/users/register").send(validUser) // 直接从响应体取令牌 accessToken = resp.body.accessToken refreshToken = resp.body.refreshToken // 也可以保存完整cookie数组后续使用 cookies = resp.header["set-cookie"] // 可选添加断言验证结果 expect(resp.statusCode).toBe(201) expect(accessToken).toBeDefined() expect(refreshToken).toBeDefined() }) // 其他需要鉴权的测试用例直接复用变量即可 it("should access protected endpoint with token", async () => { // 方式1:把token放在请求头中传递 const resp1 = await request.get("/your-protected-api") .set("Authorization", `Bearer ${accessToken}`) // 方式2:直接携带完整cookie请求,模拟浏览器行为 const resp2 = await request.get("/your-protected-api") .set("Cookie", cookies) }) afterAll(done => { mongoose.connection.close(() => { done() }) }) })
如果你需要专门验证接口返回的Cookie是否正确,写一个简单的解析工具函数即可快速提取指定Cookie的值:
// 可以放在测试文件顶部,或者公共测试工具文件中复用 const getCookieValue = (cookies: string[], cookieName: string): string | undefined => { const targetCookie = cookies.find(cookie => cookie.startsWith(`${cookieName}=`)) if (!targetCookie) return undefined // 分割字符串取出token值,忽略后面的属性配置 return targetCookie.split('=')[1].split(';')[0] }
在测试用例中使用:
it("should return correct tokens in cookies", async () => { const resp = await request.post("/users/register").send(validUser) const cookies = resp.header["set-cookie"] const accessToken = getCookieValue(cookies, "accessToken") const refreshToken = getCookieValue(cookies, "refreshToken") expect(accessToken).toBeDefined() expect(refreshToken).toBeDefined() })
如果后续接口都是依赖Cookie鉴权,不需要手动提取令牌,直接用supertest的agent实例即可,它会自动保存接口返回的所有Cookie,后续请求自动携带,完全不需要手动处理:
import server from "../server" import supertest from "supertest" import mongoose from "mongoose" import dotenv from "dotenv" dotenv.config() // 用agent代替普通request实例 const agent = supertest.agent(server) describe("Testing Auth endpoints", () => { beforeAll(done => { const PORT = process.env.PORT mongoose .connect(process.env.MONGO_STRING_TEST!) .then(() => { console.log("Connect to Atlas. Test DB.") done() }) .catch(err => console.log(err)) }) const validUser = { name: "Paul Stevens", email: "ps@g.com", password: "1234", role: "host", } it("should register successfully", async () => { const resp = await agent.post("/users/register").send(validUser) expect(resp.statusCode).toBe(201) // agent已经自动保存了返回的两个Cookie,后续请求自动携带 }) it("should access protected endpoint without manual token", async () => { // 不需要手动加Cookie或者Authorization头,agent自动携带 const resp = await agent.get("/your-protected-api") expect(resp.statusCode).toBe(200) }) afterAll(done => { mongoose.connection.close(() => { done() }) }) })
内容的提问来源于stack exchange,提问作者Tiago Brandão
相关产品推荐
相关产品推荐

