supertest翻译学习

##supertest

HTTP断言,易于构建在superagent之上。

关于

编写这个模块的动机在于提供一个高级抽象的http测试库,同时也支持superagent低级api。

开始

使用npm安装supertest并保存为开发依赖项。

1
2
3
4
npm install supertest --save-dev

//or
npm i supertest -D

安装完成后,可以使用require(‘supertest’)来调用它。

例子

你可能传递一个http服务或者一个request方法,如果服务器还没有监听连接,那么它将被绑定到一个临时端口,因此不需要跟踪端口。

supertest可以运行在任何测试框架,下面的例子没有用任何测试框架。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const request = require('supertest');
const express = require('express');

const app = express();

app.get('/user', function(req, res) {
res.status(200).json({ name: 'tobi' });
});

request(app)
.get('/user')
.expect('Content-Type', /json/)
.expect('Content-Length', '15')
.expect(200)
.end(function(err, res) {
if (err) throw err;
});

下面这个例子是和mocha结合,注意如何使用done完成任意的链式调用。

1
2
3
4
5
6
7
8
9
describe('GET /users', function() {
it('respond with json', function(done) {
request(app)
.get('/users')
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200, done);
});
});

关于上述代码有一点需要注意的是,如何你没有添加一个期望的状态码(比如说302),
superagent现在可以发送任何http错误(任何大于2XX的代码)到回调函数作为第一个参数。

如何你正在使用.end方法,.expect在断言失败的情况下不会抛出,它将会把这个断言作为一个error返回给end方法。为了获取这个
失败的测试例子,你需要重新抛出这个error或者传给done()方法, 如下:

1
2
3
4
5
6
7
8
9
10
11
12
describe('GET /users', function() {
it('respond with json', function(done) {
request(app)
.get('/users')
.set('Accept', 'application/json')
.expect(200)
.end(function(err, res) {
if (err) return done(err);
done();
});
});
});

你也可以使用promises

1
2
3
4
5
6
7
8
9
10
11
describe('GET /users', function() {
it('respond with json', function() {
return request(app)
.get('/users')
.set('Accept', 'application/json')
.expect(200)
.then(response => {
assert(response.body.email, 'foo@bar.com');
});
})
});

预期结果按照定义的顺序执行。在执行断言之前,可以使用此特性修改响应体或headers。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
describe('GET /user', function() {
it('user.name should be an case-insensitive match for "tobi"', function(done) {
request(app)
.get('/user')
.set('Accept', 'application/json')
.expect(function(res) {
res.body.id = 'some fixed id';
res.body.name = res.body.name.toUpperCase();
})
.expect(200, {
id: 'some fixed id',
name: 'TOBI'
}, done);
});
});

你可以用superagent做的事情,supertest也可以做,比如说多文件上传。

1
2
3
4
5
request(app)
.post('/')
.field('name', 'my awesome avatar')
.attach('avatar', 'test/fixtures/homeboy.jpg')
...

如何你正在测试同一主机,没必要每次都传递一个app或者url,你可以简单地用初始化app或URL重新分配请求变量,一个新的Test被
request.VERB()所创建。

1
2
3
4
5
6
7
8
9
request = request('http://localhost:5555');

request.get('/').expect(200, function(err){
console.log(err);
});

request.get('/').expect('heya', function(err){
console.log(err);
});

这里有个例子,使用mocha来展示如何持久化一个request和它的cookies:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const request = require('supertest');
const should = require('should');
const express = require('express');
const cookieParser = require('cookie-parser');

describe('request.agent(app)', function() {
const app = express();
app.use(cookieParser());

app.get('/', function(req, res) {
res.cookie('cookie', 'hey');
res.send();
});

app.get('/return', function(req, res) {
if (req.cookies.cookie) res.send(req.cookies.cookie);
else res.send(':(')
});

const agent = request.agent(app);

it('should save cookies', function(done) {
agent
.get('/')
.expect('set-cookie', 'cookie=hey; Path=/', done);
});

it('should send cookies', function(done) {
agent
.get('/return')
.expect('hey', done);
});
})

还有一个用agency.js来介绍的例子。
https://github.com/visionmedia/superagent/blob/master/test/node/agency.js

API

你可以使用任何superagent方法,包括.write(), pipe()等,还可以为了低级需求在.end()方法里使用断言。

.expect(status[, fn])

断言响应状态码

.expect(status, body[, fn])

断言响应状态码和body

.expect(body[, fn])

用字符串、正则表达式或解析体对象断言响应正文文本。

.expect(field, value[, fn])

用字符串或正则表达式断言header字段值。

.expect(function(res){})

传递自定义断言函数。它会给出响应对象检查。如果检查失败,抛出错误。

1
2
3
4
5
6
7
8
9
request(app)
.get('/')
.expect(hasPreviousAndNextKeys)
.end(done);

function hasPreviousAndNextKeys(res) {
if (!('next' in res.body)) throw new Error("missing next key");
if (!('prev' in res.body)) throw new Error("missing prev key");
}

.end(fn)

执行request并调用fn(err, res)方法

License

MIT