【译】使用supertest来测试API

我最近发现supertest是一个测试API很棒的工具. 虽然对我来说它还很新,但是这个包其实好几年前就有了.

安装

可以使用很多种方式配置supertest. 如果测试的一个外部连接, 可以像下面这样配置base url:

1
var request = require('supertest')("http://example.com");

如果要测试Express框架搭建的APP, 可以把APP的入口文件传给supertest, 让它关注APP的状态(启动/关闭)

1
2
var myApp = require('../app.js');
var request = require('supertest')(myApp);

这样写的好处是, supertest会关注APP的启动和关闭. 你就可以转注在写测试代码, 而不用关系启动APP, 配置端口等.

写测试

一旦引入了supertest, 使用起来就很简单了. 在下面的例子中, 使用Mocha这个测试框架.

1
2
3
4
5
6
7
describe('my api', function() {
it('returns hello world', function(done) {
request.
.get('/')
.expect('Hello, World!', done);
});
});

最简单的测试get接口的代码. 访问根目录”/“, 期望得到的返回是”Hello, World!”.

由于request是异步的, 把”done”作为参数(Mocha提供的). 在验证服务端的返回的时候调用它.

可以像下面这样测试一个JSON数据:

1
2
3
request.
.get('/')
.expect({message: "Hello, World!"}, done);

测试header:

1
2
3
request.
.get('/foo')
.expect('Content-Type', 'application/json', done);

测试状态码:

1
2
3
request
.get('/some-error-route')
.expect(500, 'Oops. Something went wrong', done);

发送非-GET请求:

1
2
3
4
5
var user = {name: 'Bob'};
request
.post('/create-user')
.send(user)
.expect({success:true}, done);

可以设置request的头信息:

1
2
3
4
request
.get('/foo')
.set('Accept', 'text/plain')
.expect('Content-Type', 'text/plain', done);

还可以使用正则表达式匹配header和body.

1
2
3
4
request
.get('/redirect')
.expect('Location': /\/destination/)
.expect(301, done);

如果需要串行的多个requests, 可以利用”expect”的回调来实现,如下:

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
// Kick things off
purgeUsers();

function purgeUsers() {
request
.get('/users/purge')
.expect({success:true}, checkNoUsers);
}

function checkNoUsers(err) {
if (err) done(err);
request
.get('/users')
.expect([], addUser);
}

function addUser() {
if (err) done(err);
request
.post('/users')
.send({name: 'Bob'})
.expect({success:true}, checkUsers);
}

function checkUsers(err) {
if (err) done(err);
request
.get('/users')
.expect([{name: 'Bob'}], done);
}

最后,如果要对结果做一些特殊的处理, 可以在.end()这个函数中处理:

1
2
3
4
5
6
7
var assert = require('assert');
request
.get('/foo')
.end(function(err, result) {
assert.equal(result.body.foo, 'Bar');
done();
});

可能还有很多我没有注意到的特性, 不过上面的这些都是我常用到的~

译: http://willi.am/blog/2014/07/28/test-your-api-with-supertest/