如何使用 superagent/supertest 链接 http 调用?

Posted

技术标签:

【中文标题】如何使用 superagent/supertest 链接 http 调用?【英文标题】:How to chain http calls with superagent/supertest? 【发布时间】:2014-02-01 02:43:22 【问题描述】:

我正在用 supertest 测试一个 express API。

我无法在一个测试用例中获得多个请求来使用 supertest。以下是我在测试用例中尝试过的。但是测试用例似乎只执行最后一个调用,即 HTTP GET。

it('should respond to GET with added items', function(done) 
    var agent = request(app);
    agent.post('/player').type('json').send(name:"Messi");
    agent.post('/player').type('json').send(name:"Maradona");
    agent.get('/player').set("Accept", "application/json")
        .expect(200)
        .end(function(err, res) 
            res.body.should.have.property('items').with.lengthOf(2);
            done();
    );
);

我在这里遗漏了什么,或者是否有另一种方法可以将 http 调用与 superagent 链接起来?

【问题讨论】:

【参考方案1】:

试图将其放在上面的评论中,格式不正确。

我正在使用异步,它是真正的标准并且运行良好。

it('should respond to only certain methods', function(done) 
    async.series([
        function(cb)  request(app).get('/').expect(404, cb); ,
        function(cb)  request(app).get('/new').expect(200, cb); ,
        function(cb)  request(app).post('/').send(prop1: 'new').expect(404, cb); ,
        function(cb)  request(app).get('/0').expect(200, cb); ,
        function(cb)  request(app).get('/0/edit').expect(404, cb); ,
        function(cb)  request(app).put('/0').send(prop1: 'new value').expect(404, cb); ,
        function(cb)  request(app).delete('/0').expect(404, cb); ,
    ], done);
);

【讨论】:

这应该是公认的答案。异步在这种情况下工作得非常好。 好方法!我对它进行了一些扩展,在这里查看***.com/a/45198533/449227【参考方案2】:

调用是异步的,所以你需要使用回调函数来链接它们。

it('should respond to GET with added items', function(done) 
    var agent = request(app);
    agent.post('/player').type('json').send(name:"Messi").end(function()
        agent.post('/player').type('json').send(name:"Maradona").end(function()
            agent.get('/player')
                .set("Accept", "application/json")
                .expect(200)
                .end(function(err, res) 
                    res.body.should.have.property('items').with.lengthOf(2);
                    done();
                );
        );
    );
);

【讨论】:

看看supertest-as-promised减少回调的嵌套 是否可以在不使用mochait 的情况下链接它们? supertest 自版本 2.0.0 起具有原生 Promise 支持 我无法让这个解决方案发挥作用。但是,我可以让下面的“异步”解决方案(由 Tim)工作。 这个答案是正确的,但是已经过时了,使用 async/await 可以得到相同的结果,但实现更简洁【参考方案3】:

这可以通过 promise 最优雅地解决,并且有一个非常有用的库可以将 promise 与 supertest 一起使用:https://www.npmjs.com/package/supertest-as-promised

他们的例子:

return request(app)
  .get("/user")
  .expect(200)
  .then(function (res) 
    return request(app)
      .post("/kittens")
      .send( userId: res)
      .expect(201);
  )
  .then(function (res) 
    // ... 
  );

【讨论】:

Promise 是一个不错的选择。只需要对可能需要从该链中某处的 404 恢复的情况感到厌倦。 supertest 自版本 2.0.0 起具有原生 Promise 支持【参考方案4】:

我建立在Tim’s reply 之上,但使用async.waterfall 代替,以便能够对结果进行断言测试(注意:我在这里使用Tape 而不是Mocha):

test('Test the entire API', function (assert) 
    const app = require('../app/app');
    async.waterfall([
            (cb) => request(app).get('/api/accounts').expect(200, cb),
            (results, cb) =>  assert.ok(results.body.length, 'Returned accounts list'); cb(null, results); ,
            (results, cb) =>  assert.ok(results.body[0].reference, 'account #0 has reference'); cb(null, results); ,
            (results, cb) => request(app).get('/api/plans').expect(200, cb),
            (results, cb) => request(app).get('/api/services').expect(200, cb),
            (results, cb) => request(app).get('/api/users').expect(200, cb),
        ],
        (err, results) => 
            app.closeDatabase();
            assert.end();
        
    );
);

【讨论】:

你为我节省了很多时间。目前,这是最好的答案。

以上是关于如何使用 superagent/supertest 链接 http 调用?的主要内容,如果未能解决你的问题,请参考以下文章

[精选] Mysql分表与分库如何拆分,如何设计,如何使用

如果加入条件,我该如何解决。如果使用字符串连接,我如何使用

如何使用本机反应创建登录以及如何验证会话

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]

如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?

如何使用laravel保存所有行数据每个行名或相等