如何使用 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减少回调的嵌套 是否可以在不使用mocha
或it
的情况下链接它们?
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 调用?的主要内容,如果未能解决你的问题,请参考以下文章
如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]