Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
The supertest npm package is a high-level abstraction for testing HTTP, allowing you to test your Node.js HTTP servers using a fluent API. It is built on top of the SuperAgent library and provides a simple and flexible way to assert HTTP responses in your tests.
HTTP Assertions
This feature allows you to make assertions on the HTTP response, such as the status code, content type, and body content. The code sample demonstrates how to test an Express.js route.
const request = require('supertest');
const express = require('express');
const app = express();
app.get('/user', function(req, res) {
res.status(200).json({ name: 'john' });
});
describe('GET /user', function() {
it('responds with json', function(done) {
request(app)
.get('/user')
.expect('Content-Type', /json/)
.expect('Content-Length', '15')
.expect(200, done);
});
});
Integration Testing
Supertest can be used for integration testing of an entire application by sending requests to the routes and asserting the expected responses. The code sample shows how to test for both a successful response and a 404 error.
const request = require('supertest');
const app = require('../app');
describe('Integration Testing', function() {
it('responds to /', function(done) {
request(app)
.get('/')
.expect(200, done);
});
it('404 everything else', function(done) {
request(app)
.get('/foo/bar')
.expect(404, done);
});
});
Asynchronous/Await Support
Supertest works with async/await syntax, allowing for cleaner and more readable asynchronous test code. The code sample demonstrates an asynchronous test using async/await.
const request = require('supertest');
const app = require('../app');
describe('Async/Await Support', function() {
it('responds to /', async () => {
await request(app)
.get('/')
.expect(200);
});
});
Axios is a promise-based HTTP client for the browser and Node.js. While it is not specifically designed for testing like supertest, it can be used in combination with testing frameworks to make HTTP requests and assert responses.
Nock is an HTTP server mocking and expectations library for Node.js. Unlike supertest, which performs integration tests against an actual server, nock allows you to test modules that perform HTTP requests by mocking the responses, without having to have an actual server running.
Chai-http is a plugin for the Chai assertion library that enables HTTP assertions. Similar to supertest, it allows for testing HTTP servers, but it is designed to be used with the Chai assertion library, providing a different syntax and additional assertion capabilities.
HTTP assertions made easy via superagent.
The motivation with this module is to provide a high-level abstraction for testing HTTP, while still allowing you to drop down to the lower-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 calling require('supertest');
You may pass an http.Server
, or a Function
to request()
- if the server is not
already listening for connections then it is bound to an ephemeral port for you so
there is no need to keep track of ports.
SuperTest works with any test framework, here is an example without using any test framework at all:
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;
});
Here's an example with mocha, note how you can pass done
straight to any of the .expect()
calls:
describe('GET /user', function() {
it('respond with json', function(done) {
request(app)
.get('/user')
.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 HTTP
error (anything other than a 2XX response code) to the callback as the first argument if
you do not add a status code expect (i.e. .expect(302)
).
If you are using the .end()
method .expect()
assertions that fail will
not throw - they will return the assertion as an error to the .end()
callback. In
order to fail the test case, you will need to rethrow or pass err
to done()
, as follows:
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();
});
});
});
You can also use promises
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')
})
});
});
Expectations are run in the order of definition. This characteristic can be used to modify the response body or headers before executing an assertion.
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);
});
});
Anything you can do with superagent, you can do with supertest - for example multipart file uploads!
request(app)
.post('/')
.field('name', 'my awesome avatar')
.attach('avatar', 'test/fixtures/homeboy.jpg')
...
Passing the app or url each time is not necessary, if you're testing
the same host you may simply re-assign the request variable with the
initialization app or url, a new Test
is created per request.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:
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);
});
})
There is another example that is introduced by the file agency.js
You may use any superagent methods,
including .write()
, .pipe()
etc and perform assertions in the .end()
callback
for lower-level needs.
Assert response status
code.
Assert response status
code and body
.
Assert response body
text with a string, regular expression, or
parsed body object.
Assert header field
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);
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");
}
Perform the request and invoke fn(err, res)
.
Inspired by api-easy minus vows coupling.
MIT
FAQs
SuperAgent driven library for testing HTTP servers
We found that supertest demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 6 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.