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

时间:2018-03-15 19:59:49

标签: node.js jestjs supertest 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)
    });
});

我认为这可能与我如何在语法上形成异步调用有关。但是在尝试使用beforeEachreturn语句在.end()块中返回登录调用的不同方法后,即使是异步/等待,我也确定(即放弃)代码必须正确组合。可能是别的吗?

参考文章/资源:

包装版本:

  • " koa":" ^ 2.4.1"
  • " koa-passport":" ^ 4.0.1"
  • " passport-json":" ^ 1.2.0"
  • "本地护照":" ^ 1.0.0"
  • " supertest":" ^ 3.0.0"
  • " jest":" ^ 22.1.3"

2 个答案:

答案 0 :(得分:0)

我花了一些时间在测试运行期间单步执行我的身份验证代码,并且看不到任何明显的问题。然后我想到了:如果请求本身形成不良怎么办?原来我是对的!检查了我看到的Supertest响应头中的set-cookie标题:

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

这看起来有点可疑作为单个字符串,这让我进行了一些谷歌搜索,在那里我发现在Mpert和Jest用户为Supertest代理实例设置cookie标头的方式存在差异。见:https://github.com/facebook/jest/issues/3547#issuecomment-302541653。使用Mocha的人可以毫无困难地进行身份验证,而Jest用户则可以。事实证明,有一个bug的Jest全局变量导致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)
    });
});

答案 1 :(得分:0)

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

长叹。