Buscar..


Afirmacion basica

En su nivel más básico, Unit Testing en cualquier idioma proporciona afirmaciones contra algunos resultados conocidos o esperados.

function assert( outcome, description ) { 
    var passFail = outcome ? 'pass' : 'fail'; 
    console.log(passFail, ': ', description);
    return outcome;
};

El popular método de afirmación anterior nos muestra una manera rápida y fácil de afirmar un valor en la mayoría de los navegadores web e intérpretes como Node.js con prácticamente cualquier versión de ECMAScript.

Una buena prueba de unidad está diseñada para probar una unidad de código discreta; Por lo general una función.

function add(num1, num2) { 
    return num1 + num2; 
} 
 
var result = add(5, 20); 
assert( result == 24, 'add(5, 20) should return 25...'); 

En el ejemplo anterior, el valor de retorno de la función add(x, y) o 5 + 20 es claramente 25 , por lo que nuestra afirmación de 24 debería fallar, y el método de afirmación registrará una línea de "falla".

Si simplemente modificamos el resultado esperado de la aserción, la prueba tendrá éxito y la salida resultante tendrá un aspecto similar a este.

assert( result == 25, 'add(5, 20) should return 25...');

console output:

> pass: should return 25...

Esta simple afirmación puede asegurar que en muchos casos diferentes, su función "agregar" siempre devolverá el resultado esperado y no requiere marcos o bibliotecas adicionales para funcionar.

Un conjunto de aserciones más riguroso se vería así (usando var result = add(x,y) para cada aserción):

assert( result == 0, 'add(0, 0) should return 0...');
assert( result == -1, 'add(0, -1) should return -1...');
assert( result == 1, 'add(0, 1) should return 1...');

Y la salida de la consola sería esta:

> pass: should return 0...
> pass: should return -1...
> pass: should return 1...

Ahora podemos decir con seguridad que add(x,y) ... debe devolver la suma de dos enteros . Podemos resumirlos en algo como esto:

function test__addsIntegers() {

    // expect a number of passed assertions
    var passed = 3;

    // number of assertions to be reduced and added as Booleans
    var assertions = [

        assert( add(0, 0) == 0, 'add(0, 0) should return 0...'),
        assert( add(0, -1) == -1, 'add(0, -1) should return -1...'),
        assert( add(0, 1) == 1, 'add(0, 1) should return 1...')

    ].reduce(function(previousValue, currentValue){

        return previousValue + current;

    });

    if (assertions === passed) {

        console.log("add(x,y)... did return the sum of two integers");
        return true;

    } else {

        console.log("add(x,y)... does not reliably return the sum of two integers");
        return false;

    }
}

Pruebas de unidad prometen con Mocha, Sinon, Chai y Proxyquire

Aquí tenemos una clase simple para probar que devuelve una Promise basada en los resultados de un procesador de ResponseProcessor externo que demora en ejecutarse.

Para simplificar, asumiremos que el método processResponse nunca fallará.

import {processResponse} from '../utils/response_processor';

const ping = () => {
  return new Promise((resolve, _reject) => {
    const response = processResponse(data);
    resolve(response);
  });
}

module.exports = ping;

Para probar esto podemos aprovechar las siguientes herramientas.

  1. mocha
  2. chai
  3. sinon
  4. proxyquire
  5. chai-as-promised

Uso el siguiente script de test en mi archivo package.json .

"test": "NODE_ENV=test mocha --compilers js:babel-core/register --require ./test/unit/test_helper.js  --recursive test/**/*_spec.js"

Esto me permite usar la sintaxis de es6 . Hace referencia a un test_helper que se verá como

import chai from 'chai';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import chaiAsPromised from 'chai-as-promised';
import sinonStubPromise from 'sinon-stub-promise';

chai.use(sinonChai);
chai.use(chaiAsPromised);
sinonStubPromise(sinon);

Proxyquire nos permite inyectar nuestro propio código auxiliar en lugar del ResponseProcessor externo. Entonces podemos usar sinon para espiar los métodos de ese talón. Usamos las extensiones para chai que chai-as-promised inyecta para verificar que la promesa del método ping() está fullfilled , y que eventually devuelve la respuesta requerida.

import {expect}       from 'chai';
import sinon          from 'sinon';
import proxyquire     from 'proxyquire';

let formattingStub = {
  wrapResponse: () => {}
}

let ping = proxyquire('../../../src/api/ping', {
  '../utils/formatting': formattingStub
});

describe('ping', () => {
  let wrapResponseSpy, pingResult;
  const response = 'some response';

  beforeEach(() => {
    wrapResponseSpy = sinon.stub(formattingStub, 'wrapResponse').returns(response);
    pingResult = ping();
  })

  afterEach(() => {
    formattingStub.wrapResponse.restore();
  })

  it('returns a fullfilled promise', () => {
    expect(pingResult).to.be.fulfilled;
  })

  it('eventually returns the correct response', () => {
    expect(pingResult).to.eventually.equal(response);
  })
});

Ahora, en cambio, supongamos que desea probar algo que utiliza la respuesta de ping .

import {ping} from './ping';

const pingWrapper = () => {
  ping.then((response) => {
    // do something with the response
  });
}

module.exports = pingWrapper;

Para probar el pingWrapper aprovechamos

  1. sinon
  2. proxyquire
  3. sinon-stub-promise

Como antes, Proxyquire nos permite inyectar nuestro propio código auxiliar en lugar de la dependencia externa, en este caso, el método ping que probamos anteriormente. Luego podemos usar sinon para espiar los métodos de ese código auxiliar y aprovechar la sinon-stub-promise para permitirnos returnsPromise . Esta promesa puede ser resuelta o rechazada como deseamos en la prueba, para probar la respuesta del contenedor a eso.

import {expect}   from 'chai';
import sinon      from 'sinon';
import proxyquire from 'proxyquire';

let pingStub = {
  ping: () => {}
};

let pingWrapper = proxyquire('../src/pingWrapper', {
  './ping': pingStub
});

describe('pingWrapper', () => {
  let pingSpy;
  const response = 'some response';

  beforeEach(() => {
    pingSpy = sinon.stub(pingStub, 'ping').returnsPromise();
    pingSpy.resolves(response);
    pingWrapper();
  });

  afterEach(() => {
    pingStub.wrapResponse.restore();
  });

  it('wraps the ping', () => {
    expect(pingSpy).to.have.been.calledWith(response);
  });
});


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow