Поиск…


Основное утверждение

На самом базовом уровне модульное тестирование на любом языке предоставляет утверждения против некоторых известных или ожидаемых результатов.

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

Популярный метод утверждения выше показывает нам один быстрый и простой способ утверждать ценность в большинстве веб-браузеров и интерпретаторов, таких как Node.js, практически с любой версией ECMAScript.

Хороший модульный тест предназначен для проверки сдержанной единицы кода; обычно функция.

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

В приведенном выше примере возвращаемое значение из функции add(x, y) или 5 + 20 составляет, очевидно, 25 , поэтому наше утверждение 24 должно завершиться неудачей, и метод assert будет записывать строку «fail».

Если мы просто изменим ожидаемый результат утверждения, тест будет успешным, и результат будет выглядеть примерно так.

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

console output:

> pass: should return 25...

Это простое утверждение может гарантировать, что во многих разных случаях функция «добавить» всегда будет возвращать ожидаемый результат и не требует каких-либо дополнительных фреймворков или библиотек.

Более строгий набор утверждений будет выглядеть следующим образом (с помощью var result = add(x,y) для каждого утверждения):

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

И консольный вывод будет следующим:

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

Теперь мы можем с уверенностью сказать, что add(x,y) ... должно возвращать сумму двух целых чисел . Мы можем развернуть их примерно так:

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;

    }
}

Unit Testing Promises с мокко, синонами, чаями и проксимиром

Здесь у нас есть простой класс для тестирования, который возвращает Promise на основе результатов внешнего ResponseProcessor , для выполнения которого требуется время.

Для упрощения будем считать, что метод processResponse никогда не будет терпеть неудачу.

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

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

module.exports = ping;

Чтобы проверить это, мы можем использовать следующие инструменты.

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

Я использую следующий test скрипт в файле package.json .

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

Это позволяет использовать синтаксис es6 . Он ссылается на test_helper который будет выглядеть

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 позволяет нам вводить наш собственный заглушка вместо внешнего ResponseProcessor . Затем мы можем использовать sinon чтобы шпионить за sinon методами. Мы используем расширение для chai , что chai-as-promised впрыскивает проверить , что ping() обещание методы является fullfilled , и что он в eventually возвращает нужный ответ.

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

Теперь вместо этого предположим, что вы хотите проверить что-то, что использует ответ от ping .

import {ping} from './ping';

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

module.exports = pingWrapper;

Для тестирования pingWrapper мы используем

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

Как и прежде, Proxyquire позволяет нам вводить наш собственный заглушка вместо внешней зависимости, в данном случае метод ping который мы тестировали ранее. Затем мы можем использовать sinon чтобы шпионить за sinon методами заглушки и использовать sinon-stub-promise чтобы позволить нам returnsPromise . Это обещание может быть разрешено или отклонено, как мы желаем в тесте, чтобы проверить ответ обертки на это.

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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow