HTTP agent

Testing any HTTP servers (response and request) from Node.js with the HTTP agent.

supertest (and superagent) are included in Unit.JS to as httpAgent for easily make HTTP assertions.

This documentation below is an adaptation of the official "supertest" documentation, that is written by the contributors of the "supertest" module.

Example

test.httpAgent('http://localhost')
  .get('/user')
  .expect('Content-Type', /json/)
  .expect('Content-Length', '20')
  .expect(200)
  .end(function(err, res){
    if (err) {
      test.fail(err.message);
    }
  });

Also, 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.

var test    = require('unit.js');
var express = require('express');
var app     = express();

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

test.httpAgent(app)
  .get('/user')
  .expect('Content-Type', /json/)
  .expect('Content-Length', '20')
  .expect(200)
  .end(function(err, res){
    if (err) {
      test.fail(err.message);
    }
  });

Here's an example with mocha, note how you can pass done straight to any of the .expect() calls:

describe('GET /users', function(){
  it('respond with json', function(done){
    test.httpAgent(app)
      .get('/user')
      .set('Accept', 'application/json')
      .expect('Content-Type', /json/)
      .expect(200, done);
  })
})

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){
    test.httpAgent(app)
      .get('/user')
      .set('Accept', 'application/json')
      .expect(200)
      .end(function(err, res){
        if (err) {
          return done(err);
        }

        done();
      });
  })
})

Anything you can do with supertest and superagent, you can do with httpAgent - for example multipart file uploads!

test.httpAgent(app)
.post('/')
.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 = test.httpAgent('http://localhost:5555');

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

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

API

You may use any superagent methods, including .write(), .pipe() etc and perform assertions in the .end() callback for lower-level needs.

.expect(status[, fn])

Assert response status code.

.expect(status, body[, fn])

Assert response status code and body.

.expect(body[, fn])

Assert response body text with a string, regular expression, or parsed body object.

.expect(field, value[, fn])

Assert header field value with a string or regular expression.

.expect(function(res) {})

Pass a custom assertion function. It'll be given the response object to check. If the response is ok, it should return falsy, most commonly by not returning anything. If the check fails, throw an error or return a truthy value like a string that'll be turned into an error.

Here the string or error throwing options are both demonstrated:

  test.httpAgent(app)
    .get('/')
    .expect(hasPreviousAndNextKeys)
    .end(done);

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

.end(fn)

Perform the request and invoke fn(err, res).