Supertest

repository·master·Indexed 12 days ago

https://github.com/forwardemail/supertest

A high-level abstraction for testing HTTP servers, built on top of superagent. Supertest allows developers to make assertions about HTTP responses and supports HTTP/2, session-based testing via request.agent(), and specialized cookie assertions. It is compatible with major test frameworks and supports callbacks, Promises, and async/await patterns. Version 7.2.2.

Tokens
6.8K
Snippets
24
Records
29
Agent score
95%

What's inside Supertest

  1. How custom assertions and order of execution work

    master

    Expectations in supertest are executed in the order they are defined. This allows you to use a custom .expect(fn) to modify the response object (e.g., normalizing data) before subsequent assertions run.

    request(app)
      .post('/user')
      .send('name=john')
      .expect(function(res) {
        // Modify response before next assertion
        res.body.id = 'some fixed id';
        res.body.name = res.body.name.toLowerCase();
      })
      .expect(200, {
        id: 'some fixed id',
        name: 'john'
      }, done);
  2. Assert cookies in Supertest requests

    master

    Supertest provides a cookies utility to assert the presence, absence, and properties of cookies in HTTP responses. You can access these assertions via request.cookies and pass them into the .expect() method of a Supertest chain. Assertions are chainable.

    const request = require('supertest');
    const express = require('express');
    const cookies = request.cookies;
    
    const app = express();
    
    app.get('/users', function(req, res) {
      res.cookie('alpha', 'one', { domain: 'domain.com', path: '/', httpOnly: true });
      res.send(200, { name: 'tobi' });
    });
    
    request(app)
      .get('/users')
      .expect(200)
      .expect(cookies.set({ name: 'alpha', options: ['domain', 'path', 'httponly'] }))
      .expect(cookies.not('set', { name: 'bravo' }))
      .end(function(err, res) {
        if (err) throw err;
      });
  3. Manage cookies and sessions with request.agent()

    master

    Use request.agent(app) to create an agent that persists cookies across multiple requests. This is essential for testing authenticated sessions or workflows where one request sets a cookie and a subsequent request relies on it.

    const agent = request.agent(app);
    
    // This request sets a cookie
    agent.get('/').expect('set-cookie', 'cookie=hey; Path=/', done);
    
    // This request will automatically send the cookie back
    agent.get('/return').expect('hey', done);
  4. Get started with supertest

    master

    Supertest provides a high-level abstraction for testing HTTP by wrapping superagent. You can pass an http.Server or a Function (like an Express app) to request(). If the server is not already listening, supertest automatically binds it to an ephemeral port.

    To enable the HTTP/2 protocol, pass an options object with { http2: true } to request() or request.agent().

    const request = require('supertest');
    const express = require('express');
    const app = express();
    
    app.get('/user', (req, res) => res.status(200).json({ name: 'john' }));
    
    // Basic usage
    request(app)
      .get('/user')
      .expect('Content-Type', /json/)
      .expect(200)
      .end((err, res) => {
        if (err) throw err;
      });
    
    // Enabling HTTP/2
    request(app, { http2: true })
      .get('/user')
      .expect(200)
      .end((err, res) => {
        if (err) throw err;
      });
  5. Use supertest with Mocha (Callbacks, Promises, and Async/Await)

    master

    Supertest is compatible with all major test frameworks.

    Using Callbacks (done)

    When using Mocha's done callback, you can pass done directly into .expect() calls. If using .end(), ensure you pass the error to done(err) to fail the test correctly.

    Using Promises

    Return the request chain from your test to use .then() for assertions.

    Using Async/Await

    Await the request and then perform assertions on the returned response object.

    // Callback pattern
    describe('GET /user', function() {
      it('responds with json', function(done) {
        request(app)
          .get('/user')
          .expect('Content-Type', /json/)
          .expect(200, done);
      });
    });
    
    // Promise pattern
    describe('GET /users', function() {
      it('responds with json', function() {
        return request(app)
          .get('/users')
          .expect(200)
          .then(response => {
             expect(response.body.email).toEqual('foo@bar.com');
          });
      });
    });
    
    // Async/Await pattern
    describe('GET /users', function() {
      it('responds with json', async function() {
        const response = await request(app).get('/users');
        expect(response.status).toEqual(200);
      });
    });
  6. Use cookie assertions in Supertest

    master

    Supertest provides a cookie assertion utility to validate cookies in both request headers (Cookie) and response headers (Set-Cookie). You initialize the assertion engine by calling the exported function with an optional secret (for signed cookies) and a list of asserts (assertion methods).

    To use it, pass the response object (or an object containing req and headers) to the resulting Assertion function. The assertion engine will automatically parse the cookies and run your chain of requirements.

    Initialization Signature: const assertion = require('./lib/cookies/assertion')(secret, asserts);

    • secret: null | string | string[]. Used to unsign cookie values if they are signed.
    • asserts: function | function[]. An array of assertion methods (like .set(), .contain(), etc.) to be executed.
    const cookieAssertion = require('./lib/cookies/assertion')(['my-secret']);
    
    // In your test:
    const res = await request(app).get('/path');
    cookieAssertion(res)
      .set({ name: 'session' })
      .contain({ name: 'session', value: '123' });
  7. Initialize cookie assertions with cookies()

    master

    The cookies([secret], [asserts]) function returns an assertion function for use with .expect().

    • secret: A String or array of strings used for cookie signature secrets. Required if testing signed cookies.
    • asserts(req, res): A function or array of functions. If a custom assertion fails, it should throw an error.
    const cookies = request.cookies(secret, asserts);
  8. Configure HTTP/2 support in TestAgent

    master

    You can instruct TestAgent to use HTTP/2 by passing http2: true in the options object during initialization. This will cause the agent to wrap your application in an http2.createServer() instance.

    Note: This requires a version of Node.js that supports the http2 module. If the module is unavailable, an error will be thrown: supertest: this version of Node.js does not support http2.

    const request = require('supertest');
    const app = require('./app');
    
    // Initialize agent with HTTP/2 enabled
    const agent = request.agent(app, { http2: true });
  9. Reference: .expect() assertion methods

    master

    The .expect() method is used to assert various parts of the HTTP response. Assertions are run in the order defined.

    // Assert response status code
    .expect(status)
    .expect(status, fn)
    
    // Assert status code and body
    .expect(status, body)
    .expect(status, body, fn)
    
    // Assert response body (string, regex, or object)
    .expect(body)
    .expect(body, fn)
    
    // Assert header field and value
    .expect(field, value)
    .expect(field, value, fn)
    
    // Custom assertion function
    .expect(function(res) {
      // If check fails, throw an error
      if (!('next' in res.body)) throw new Error("missing next key");
    })
  10. Reference: .end(fn)

    master

    The .end(fn) method performs the request and invokes the provided callback function with fn(err, res). If assertions fail, the error is passed as the first argument to the callback.

    request(app)
      .get('/user')
      .expect(200)
      .end(function(err, res) {
        // err contains assertion failures or network errors
        // res contains the response object
      });
  11. Reference: Cookie assertion methods

    master

    The following methods are available on the object returned by cookies() to validate cookie behavior in responses. Most methods accept an optional assert boolean modifier (defaulting to true).

    #### .set(expects, [assert])
    Assert that cookie and options are set.
    - `expects`: Object or array of objects containing `name` (String) and optional `options` (Array).
    
    #### .reset(expects, [assert])
    Assert that cookie is set and was already set (present in request headers).
    - `expects`: Object or array of objects containing `name` (String).
    
    #### .new(expects, [assert])
    Assert that cookie is set and was NOT already set (NOT in request headers).
    - `expects`: Object or array of objects containing `name` (String).
    
    #### .renew(expects, [assert])
    Assert that cookie is set with a strictly greater `expires` or `max-age` than the given value.
    - `expects`: Object or array of objects containing `name` (String) and `options` (Object).
    - `options.expires`: String UTC expiration for original cookie.
    - `options.max-age`: Integer ttl in seconds for original cookie.
    
    #### .contain(expects, [assert])
    Assert that cookie is set with value and contains specific options. Requires `cookies(secret)` if cookies are signed.
    - `expects`: Object or array of objects containing:
      - `name`: String
      - `value`: Optional string unsigned value
      - `options`: Optional object containing `domain`, `path`, `expires`, `max-age`, `secure`, or `httponly`.
    
    #### .not(method, expects)
    Syntactic sugar to call any assertion method with the `assert` modifier set to `false`.
    - `method`: String name of the method to negate.
    - `expects`: Arguments corresponding to the chosen method.