无法使用 Jest、Supertest、Passport、Koa2 在测试中发送经过身份验证的请求

Unable to send authenticated request in tests using Jest, Supertest, Passport, Koa2

尽管我尽最大努力正确编写测试代码来验证设置块或之前的 describe/it 块中的请求代理,但我在后续 describe/it 块中从代理发出的任何请求都无法完成,因为 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 块中返回登录调用的不同方式后,甚至 async/await,我已经确定(即放弃)代码必须正确组合。会不会是别的东西?

引用articles/resources:

包版本:

我在测试运行期间花了一些时间逐步检查我的授权代码,但没有发现任何明显的问题。然后我有一个想法:如果请求本身格式不正确怎么办。事实证明我是对的!检查超测响应 header 中的 set-cookie header 我看到:

[ 'koa:sess=eyJwYXNzcG9ydCI6eyJ1c2VyIjoxfSwiX2V4cGlyZSI6MTUyMTIyODg0NTU5OSwiX21heEFnZSI6ODY0MDAwMDB9; path=/; httponly,koa:sess.sig=EEZzgcg3bx8bm_FXRMobrr8_Yts; path=/; httponly' ]

作为单个字符串,这看起来有点可疑,这让我进行了更多谷歌搜索,我发现在为 Mocha 和 Jest 用户设置 cookie headers 的方式上存在差异作为全局Supertest 代理实例上的状态。请参阅: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 Jest 全局变量导致 cookie 以单个字符串形式出现,而不是每个 cookie 的单独字符串数组——这是 Supertest 正确格式化请求所需要的。

这是一个基于问题中代码的变通方法,我们在其中正确地将有问题的 Jest 字符串解析为 Setup 块内 cookie/session 数据的作用域变量:

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)
    });
});

我无法得到 internetross 的答案。经过大量调查,我终于找到了这个:https://github.com/facebook/jest/issues/3547#issuecomment-397183207.

我不得不更换

session = response.headers['set-cookie'][0]
               .split(',')
               .map(item => item.split(';')[0])
               .join('; ')

  response.headers['set-cookie'][0]
    .split(',')
    .map(item => item.split(';')[0])
    .forEach(c => agent.jar.setCookie(c));

长叹一口气