无法在使用Jest,Supertest,Passport,Koa2的测试中发送经过身份验证的请求 [英] Unable to send authenticated request in tests using Jest, Supertest, Passport, Koa2

查看:199
本文介绍了无法在使用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?

参考文章/资源:

  • 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆