【问题标题】:Unable to send authenticated request in tests using Jest, Supertest, Passport, Koa2无法在使用 Jest、Supertest、Passport、Koa2 的测试中发送经过身份验证的请求
【发布时间】:2018-08-24 18:44:59
【问题描述】:

尽管我尽最大努力正确编写测试代码来验证 Setup 块或之前的 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 块中的登录调用的不同方法之后,我已经确定(即放弃)代码必须正确组合。会不会是别的?

参考文章/资源:

软件包版本:

  • “koa”:“^2.4.1”
  • “koa-passport”:“^4.0.1”
  • “passport-json”:“^1.2.0”
  • “本地护照”:“^1.0.0”
  • “超级测试”:“^3.0.0”
  • “笑话”:“^22.1.3”

【问题讨论】:

  • 在试图找出一个非常相似的问题时遇到了您的大部分文章/资源:stackoverflow.com/questions/60914997/…。请问你能解释一下吗?
  • @HarryLincoln 抱歉,从那以后我没有接触过这段代码或处理过类似的问题,所以我目前无法提供帮助。
  • 感谢您一如既往地回复我@internetross!

标签: node.js jestjs supertest koa2


【解决方案1】:

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

[ '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 正确格式化请求所需要的。

这是基于问题中的代码的解决方法,我们将错误的 Jest 字符串正确解析为设置块内 cookie/会话数据的范围变量:

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

【讨论】:

    【解决方案2】:

    我无法得到 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));
    

    叹了口气。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-20
      • 2023-03-17
      • 2017-01-29
      • 2020-12-11
      • 1970-01-01
      • 2019-03-29
      • 2021-08-30
      • 1970-01-01
      相关资源
      最近更新 更多