Zoeken…


Basis bewering

Op het meest basale niveau biedt Unit Testing in elke taal beweringen tegen bekende of verwachte resultaten.

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

De populaire assertiemethode hierboven laat ons een snelle en eenvoudige manier zien om een waarde te bevestigen in de meeste webbrowsers en -interpreters zoals Node.js met vrijwel elke versie van ECMAScript.

Een goede eenheidstest is ontworpen om een discrete eenheid code te testen; meestal een functie.

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

In het bovenstaande voorbeeld is de retourwaarde van de functie add(x, y) of 5 + 20 duidelijk 25 , dus onze bewering van 24 moet mislukken en de assert-methode registreert een "fail" -regel.

Als we eenvoudigweg onze verwachte uitkomst van de bewering wijzigen, zal de test slagen en zou de resulterende output er ongeveer zo uitzien.

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

console output:

> pass: should return 25...

Deze eenvoudige bewering kan ervoor zorgen dat in veel verschillende gevallen uw "toevoegen" -functie altijd het verwachte resultaat oplevert en geen extra frameworks of bibliotheken vereist om te werken.

Een meer rigoureuze set beweringen zou er zo uitzien (met var result = add(x,y) voor elke bewering):

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...');

En console-uitvoer zou dit zijn:

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

We kunnen nu veilig zeggen dat add(x,y) ... de som van twee gehele getallen moet retourneren . We kunnen deze samenvatten in zoiets als dit:

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;

    }
}

Beloftestests met Mocha, Sinon, Chai en Proxyquire

Hier moeten we een eenvoudige klasse testen die een Promise retourneert op basis van de resultaten van een externe ResponseProcessor die tijd kost om uit te voeren.

Voor simplicty gaan we ervan uit dat de processResponse methode zal nooit falen.

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

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

module.exports = ping;

Om dit te testen kunnen we de volgende tools gebruiken.

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

Ik gebruik het volgende test in mijn package.json bestand.

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

Hiermee kan ik de syntaxis van es6 gebruiken. Het verwijst naar een test_helper die eruit zal zien

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 kunnen we onze eigen stub injecteren in plaats van de externe ResponseProcessor . We kunnen dan sinon om de methoden van die stomp te bespioneren. We gebruiken de uitbreidingen van chai dat chai-as-promised injecteert om te controleren of de ping() belofte methode wordt fullfilled , en dat zij eventually het verwachte antwoord terug.

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);
  })
});

Laten we nu in plaats daarvan aannemen dat u iets wilt testen dat de reactie van ping .

import {ping} from './ping';

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

module.exports = pingWrapper;

Om de pingWrapper te testen, pingWrapper we gebruik van

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

Zoals eerder, laat Proxyquire ons toe onze eigen stub te injecteren in de plaats van de externe afhankelijkheid, in dit geval de ping methode die we eerder hebben getest. We kunnen dan sinon om de methoden van die stomp te bespioneren en sinon-stub-promise gebruiken om ons in returnsPromise te stellen om terug te returnsPromise . Deze belofte kan vervolgens worden opgelost of afgewezen zoals we in de test wensen, om de reactie van de verpakking daarop te testen.

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow