无法在使用Jest,Supertest,Passport,Koa2的测试中发送经过身份验证的请求 [英] Unable to send authenticated request in tests using Jest, Supertest, Passport, Koa2
问题描述
尽管我尽最大努力在Setup块或先前的describe/it块中正确编写测试代码以对请求代理进行身份验证,但我在随后的describe/it块中从代理提出的任何请求都永远不会完成为200.
Despite my best attempts to correctly write test code to authenticate a request agent in Setup blocks or previous describe/it blocks, any request I make from the agent in subsequent describe/it blocks never completes as 200.
示例代码:
const request = require('supertest');
const server = require('../server');
let agent = request.agent(server);
let fakePerson = null;
beforeEach(async (done) => {
fakePerson = await Person.createMock();
agent.post(‘/login’)
.send({
email: ‘test@user.com’,
password: ‘password’
})
.end(function(err, res) {
if (err) throw err;
done();
});
});
describe('GET /users/:id', () => {
it ('renders user profile', () => {
return agent
.get(`/users/${fakePerson.id}`)
.expect(200)
});
});
我认为这可能与我在语法上形成异步调用的方式有关.但是,在尝试使用return
,.end()
语法,甚至异步/等待尝试以不同方式返回beforeEach
块中的登录调用之后,我确定(即放弃了)必须正确地编写代码.可能还有其他东西吗?
I thought it might have something to do with how I was forming the async calls syntactically. But after trying different ways of returning the login call in the beforeEach
block using return
, .end()
syntax, even async/await, I've determined (ie given up) that the code must be composed properly. Could it be something else?
参考文章/资源:
- 如何通过Passport认证超级测试请求?
- https://medium.com/@ juha.a.hytonen/testing-authenticated-requests-with-supertest-325ccf47c2bb
- https://gist.github.com/joaoneto/5152248
- https://medium.com/@bill_broughton /testing-with-authenticated-routes-in-express-6fa9c4c335ca
- https://github.com/visionmedia/supertest/issues/46
- How to authenticate Supertest requests with Passport?
- https://medium.com/@juha.a.hytonen/testing-authenticated-requests-with-supertest-325ccf47c2bb
- https://gist.github.com/joaoneto/5152248
- https://medium.com/@bill_broughton/testing-with-authenticated-routes-in-express-6fa9c4c335ca
- https://github.com/visionmedia/supertest/issues/46
打包版本:
- "koa":"^ 2.4.1"
- "koa护照":"^ 4.0.1"
- "passport-json":"^ 1.2.0"
- 本地护照":"^ 1.0.0"
- 超级测试":"^ 3.0.0"
- 玩笑":"^ 22.1.3"
推荐答案
在测试运行期间,我花了一些时间逐步浏览我的身份验证代码,但看不到任何明显的问题.然后我有个想法:如果请求本身构成错误,该怎么办.原来我是对的!检查我看到的Supertest响应标头中的set-cookie
标头:
I took some time stepping through my auth code during test runs and couldn't see any obvious problem. Then I had a thought: what if the request itself was ill formed. Turns out I was right! Inspecting the set-cookie
header in the Supertest response headers I saw:
[ 'koa:sess=eyJwYXNzcG9ydCI6eyJ1c2VyIjoxfSwiX2V4cGlyZSI6MTUyMTIyODg0NTU5OSwiX21heEFnZSI6ODY0MDAwMDB9; path=/; httponly,koa:sess.sig=EEZzgcg3bx8bm_FXRMobrr8_Yts; path=/; httponly' ]
这看起来像一个单个字符串有点可疑,这导致我进行了更多搜索,发现在Supertest代理实例上为Mocha和Jest用户设置cookie头作为全局状态的方式有所不同.请参阅: https://github.com/facebook/jest/issues/3547# issuecomment-302541653 .使用Mocha的人们可以轻松进行身份验证,而Jest用户则可以.原来,存在一个带有Jest全局变量的 bug 导致了Cookie每个Cookie都以单个字符串而不是单独的字符串数组的形式出现-这是Supertest正确格式化请求的格式.
This looked a little suspicious as a single string, which led me to some more googling where I discovered that there were differences in the way that cookie headers were being set for Mocha and Jest users as global state on the Supertest agent instance. See: https://github.com/facebook/jest/issues/3547#issuecomment-302541653. Folks using Mocha had no trouble authenticating, while Jest users did. Turns out there is a bug with Jest globals that is causing the cookie to come in as a single string rather than an array of separate strings for each cookie--which is what Supertest needs to format the request properly.
这是一个基于问题代码的解决方法,其中我们将错误的Jest字符串正确解析为Setup块中Cookie/会话数据的作用域变量:
Here is a workaround based on the code in the question where we correctly parse the buggy Jest string to a scoped variable for the cookie/session data inside the Setup block:
const request = require('supertest');
const server = require('../server');
let agent = request.agent(server);
let fakePerson = null;
let session = null;
beforeEach(async () => {
fakePerson = await Person.createMock();
agent.post(‘/login’)
.send({
email: fakePerson.email,
password: fakePerson.password’
})
.then(res => {
session = res
.headers['set-cookie'][0]
.split(',')
.map(item => item.split(';')[0])
.join(';')
expect(res.status).toEqual(200)
});
});
describe('GET /users/:id', () => {
it ('renders user profile', () => {
return agent
.get(`/users/${fakePerson.id}`)
.set('Cookie', session)
.expect(200)
});
});
这篇关于无法在使用Jest,Supertest,Passport,Koa2的测试中发送经过身份验证的请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!