- Notifications
You must be signed in to change notification settings - Fork777
🕷 Super-agent driven library for testing node.js HTTP servers using a fluent API. Maintained for@forwardemail,@ladjs,@spamscanner,@breejs,@cabinjs, and@lassjs.
License
forwardemail/supertest
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
HTTP assertions made easy viasuperagent. Maintained forForward Email andLad.
The motivation with this module is to provide a high-level abstraction for testingHTTP, while still allowing you to drop down to thelower-level API provided by superagent.
Install supertest as an npm module and save it to your package.json file as a development dependency:
npm install supertest --save-dev
Once installed it can now be referenced by simply callingrequire('supertest');
You may pass anhttp.Server
, or aFunction
torequest()
- if the server is notalready listening for connections then it is bound to an ephemeral port for you sothere is no need to keep track of ports.
supertest works with any test framework, here is an example without using anytest framework at all:
constrequest=require('supertest');constexpress=require('express');constapp=express();app.get('/user',function(req,res){res.status(200).json({name:'john'});});request(app).get('/user').expect('Content-Type',/json/).expect('Content-Length','15').expect(200).end(function(err,res){if(err)throwerr;});
To enable http2 protocol, simply append an options torequest
orrequest.agent
:
constrequest=require('supertest');constexpress=require('express');constapp=express();app.get('/user',function(req,res){res.status(200).json({name:'john'});});request(app,{http2:true}).get('/user').expect('Content-Type',/json/).expect('Content-Length','15').expect(200).end(function(err,res){if(err)throwerr;});request.agent(app,{http2:true}).get('/user').expect('Content-Type',/json/).expect('Content-Length','15').expect(200).end(function(err,res){if(err)throwerr;});
Here's an example with mocha, note how you can passdone
straight to any of the.expect()
calls:
describe('GET /user',function(){it('responds with json',function(done){request(app).get('/user').set('Accept','application/json').expect('Content-Type',/json/).expect(200,done);});});
You can useauth
method to pass HTTP username and password in the same way as in thesuperagent:
describe('GET /user',function(){it('responds with json',function(done){request(app).get('/user').auth('username','password').set('Accept','application/json').expect('Content-Type',/json/).expect(200,done);});});
One thing to note with the above statement is that superagent now sends any HTTPerror (anything other than a 2XX response code) to the callback as the first argument ifyou do not add a status code expect (i.e..expect(302)
).
If you are using the.end()
method.expect()
assertions that fail willnot throw - they will return the assertion as an error to the.end()
callback. Inorder to fail the test case, you will need to rethrow or passerr
todone()
, as follows:
describe('POST /users',function(){it('responds with json',function(done){request(app).post('/users').send({name:'john'}).set('Accept','application/json').expect('Content-Type',/json/).expect(200).end(function(err,res){if(err)returndone(err);returndone();});});});
You can also use promises:
describe('GET /users',function(){it('responds with json',function(){returnrequest(app).get('/users').set('Accept','application/json').expect('Content-Type',/json/).expect(200).then(response=>{expect(response.body.email).toEqual('foo@bar.com');})});});
Or async/await syntax:
describe('GET /users',function(){it('responds with json',asyncfunction(){constresponse=awaitrequest(app).get('/users').set('Accept','application/json')expect(response.headers["Content-Type"]).toMatch(/json/);expect(response.status).toEqual(200);expect(response.body.email).toEqual('foo@bar.com');});});
Expectations are run in the order of definition. This characteristic can be usedto modify the response body or headers before executing an assertion.
describe('POST /user',function(){it('user.name should be an case-insensitive match for "john"',function(done){request(app).post('/user').send('name=john')// x-www-form-urlencoded upload.set('Accept','application/json').expect(function(res){res.body.id='some fixed id';res.body.name=res.body.name.toLowerCase();}).expect(200,{id:'some fixed id',name:'john'},done);});});
Anything you can do with superagent, you can do with supertest - for example multipart file uploads!
request(app).post('/').field('name','my awesome avatar').field('complex_object','{"attribute": "value"}',{contentType:'application/json'}).attach('avatar','test/fixtures/avatar.jpg')...
Passing the app or url each time is not necessary, if you're testingthe same host you may simply re-assign the request variable with theinitialization app or url, a newTest
is created perrequest.VERB()
call.
request=request('http://localhost:5555');request.get('/').expect(200,function(err){console.log(err);});request.get('/').expect('heya',function(err){console.log(err);});
Here's an example with mocha that shows how to persist a request and its cookies:
constrequest=require('supertest');constshould=require('should');constexpress=require('express');constcookieParser=require('cookie-parser');describe('request.agent(app)',function(){constapp=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);elseres.send(':(')});constagent=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);});});
There is another example that is introduced by the fileagency.js
Here is an example where 2 cookies are set on the request.
agent(app).get('/api/content').set('Cookie',['nameOne=valueOne;nameTwo=valueTwo']).send().expect(200).end((err,res)=>{if(err){returndone(err);}expect(res.text).to.be.equal('hey');returndone();});
You may use anysuperagent methods,including.write()
,.pipe()
etc and perform assertions in the.end()
callbackfor lower-level needs.
Assert responsestatus
code.
Assert responsestatus
code andbody
.
Assert responsebody
text with a string, regular expression, orparsed body object.
Assert headerfield
value
with a string or regular expression.
Pass a custom assertion function. It'll be given the response object to check. If the check fails, throw an error.
request(app).get('/').expect(hasPreviousAndNextKeys).end(done);functionhasPreviousAndNextKeys(res){if(!('next'inres.body))thrownewError("missing next key");if(!('prev'inres.body))thrownewError("missing prev key");}
Perform the request and invokefn(err, res)
.
Inspired byapi-easy minus vows coupling.
MIT
About
🕷 Super-agent driven library for testing node.js HTTP servers using a fluent API. Maintained for@forwardemail,@ladjs,@spamscanner,@breejs,@cabinjs, and@lassjs.
Topics
Resources
License
Code of conduct
Contributing
Security policy
Uh oh!
There was an error while loading.Please reload this page.