Wednesday, April 13, 2022

Testing Express based apps

All of the examples of automated testing Express based apps that I have found use supertest. But supertest is based on superagent and I don't like the API of superagent and, therefore, supertest.

But it is not necessary to use supertest. All it does is run an instance of the app and submit queries to it, then muddle assertions with the HTTP client. It is easy, more flexible and cleaner to run the app directly then use whatever means to submit requests and assert assertions: hopefully from independent packages.

For example:


'use strict';

const t = require('tape');
const app = require('../app');
const http = require('http');
const axios = require('axios');

const server = http.createServer(app);
server.listen(0, '127.0.0.1');
server.on('listening', () => {
  const addr = server.address();
  const address = addr.address;
  const port = addr.port;
  console.log('addr: ', addr);
  console.log('listening on ' + address + ':' + port);
  runTests(port)
  .then(() => {
    server.close();
  })
  .catch(err => {
    console.log('tests failed with: ', err);
  });
});

function runTests (port) {
  return new Promise((resolve, reject) => {
    const request = axios.create({
      baseURL: 'http://localhost:' + port + '/'
    });

    t.test('GET / returns 200', (t) => {
      request({
        url: '/',
      })
      .then(res => {
        t.equal(res.status, 200, 'Status is 200');
      })
      .catch(err => {
        t.fail(err);
      })
      .finally(() => {
        t.end();
      });
    });
 

    t.onFinish(() => {
      resolve();
    });

    t.onFailure(() => {
      reject(new Error('something went wrong'));
    });
  });
}


This is simple enough: almost as simple as using supertest, and it has advantages:

  • Use any http client code you like
  • Use any assertion library you like

 

No comments:

Labels