【问题标题】:How to chain http calls with superagent/supertest?如何使用 superagent/supertest 链接 http 调用?
【发布时间】: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 链接起来?

【问题讨论】:

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

    【讨论】:

    【解决方案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();
            }
        );
    });
    

    【讨论】:

    • 你为我节省了很多时间。目前,这是最好的答案。
    猜你喜欢
    • 2016-11-13
    • 2018-12-28
    • 2016-05-28
    • 2013-01-23
    • 2016-03-05
    • 1970-01-01
    • 1970-01-01
    • 2016-03-10
    • 2018-03-12
    相关资源
    最近更新 更多