Testing usando Hapi.js y Lab

Estoy empezando a crear un api usando hapi.js, todo es bastante sencillo y muy divertido, pero no he creado nada de testing y eso no es nada bueno. Revisando su cuenta de github encuentro el tool que usan para testing: Lab.

Luego de leer un poco su documentación me convence y pienso probarlo. Voy a usar el código de esta nueva API para congresistas que estoy creando

https://github.com/eperedo/congress-api/

Lo primero es instalar lab via npm:

npm install lab --save-dev  

El flag --save-dev es para guardarlo como una dependencia de development ya que en un entorno de producción no necesito este tool, más sobre flags para el comando install de npm en su documentación.

Quiero crear testing para la ruta que tengo creada en el API, lo único que hace esa ruta es devolver el mensaje Peruvian Congress API.
Creo un archivo llamado main.integration.test.js y dentro de el lo primero que hago es referenciar lab y exportar el método script(), también hacemos una referencia al archivo server ya que es la base de nuestra aplicación y nos sirve para simular requests hacia nuestras rutas.

var assert = require('assert'),  
    Lab = require('lab'),
    lab = exports.lab = Lab.script(),
    server = require('./../server');

Assert es el módulo que por defecto viene en nodejs para el uso de testing, más información en su documentación.
Ahora si puedo crear un test usando (quién lo diría) el método test, esta parte es bastante familiar a otros tools como mocha o jasmine.

lab.test('main route should return message', function (done) {  
    var route = {
        method: 'GET',
        url: '/'
    };
});

Lo primero es indicar al método test la descripción que espero que haga el test, en este caso retornar el mensaje, el segundo parámetro es una función que contiene el código que voy a testear, a su vez esta función lleva un callback como parámetro done que debe usarse obligatoriamente para informar a lab que un test ha terminado, sino obtendremos un timeout lanzando un error.

Dentro de la función creamos un objeto dónde replicamos la ruta que queremos probar. Usamos el método inject al que podemos decirle que ruta queremos probar y esto ejecutará el handler asociado a esa ruta.
El segundo parámetro del método inject es el que nos retorna un objeto con la respuesta de la ruta. Acá es dónde tenemos que hacer la comprobación de nuestra prueba usando assert.

server  
    .inject(route, function (response) {
        assert.equal(response.result, 'Peruvian Congress API');
        done();
});

Solo debemos de comprobar que la propiedad result del objeto response sea igual al string Peruvian Congress API ya que ese es el resultado que esperamos que se retorne desde el handler de la ruta main.
El método done simplemente es para indicarle que ahí se acaba el testing, este callback tendrá más sentido cuando tengamos cosas más complejas a probar y se ejecuten de forma asíncrona.

El código del testing al final queda así:

var assert = require('assert'),  
        Lab = require('lab'),
        lab = exports.lab = Lab.script(),
        server = require('./../server');

lab.test('main route should return message', function (done) {  
    var route = {
        method: 'GET',
        url: '/'
    };

    server
        .inject(route, function (response) {
            assert.equal(response.result, 'Peruvian Congress API');
            done();
        });
});

Para ejecutar esta prueba voy al archivo package.json y dentro de scripts agrego el comando test con el siguiente valor:

  "scripts": {
    "start": "node src/index.js",
    "test": "lab src --coverage --pattern .test --verbose"
  },

Parece complicado pero es muy sencillo de entender, primero usamos el comando lab que permite ejecutar las pruebas, luego le decimos que busque estas pruebas en la carpeta src, el flag --coverage es para que usemos code coverage, esto permite que lab nos diga que porcentaje de nuestro código ha sido probado. Seguimos con el flag --pattern que me permite el patrón que debe seguir para ejecutar los tests en este caso le digo que busque todos los archivos javascript que contengan la palabra .test. Por último --verbose es pues... ehh.. para decirle que la salida sea verbosa :)

Listo, ahora ejecuto en la consola npm test y obtengo lo siguiente

hapijs lab testing

Ya tengo mi API configurada con lab para realizar testing incluyendo code coverage.
Código completo en mi cuenta de github:

https://github.com/eperedo/congress-api/tree/testing-lab