##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