Mocha тесты выполняются до того, как обещание получает данные - PullRequest
0 голосов
/ 30 ноября 2018

Тестовые случаи (Test1, Test2) выполняются до получения данных обещанием.Это файл mockExecution.js

describe('AC 1: This is suite one', ()=>
{
    before((done)=>
    {
        promiseResp.then((data) => {
            console.log("i am in the promise");
            responseData = data;
            process.exit(0);
        }, (err) => {
            console.log('promiseResp.err', err);
            process.exit(1);
        })
        done();
    })
    it('Test1', (done)=>
    {
        expect(responseData.measure.abc).not.toBe(responseData.measure_list.abc);
        done();
    });

    it('Test2', (done)=>
    {

        expect(responseData.measure.abc).not.toBe(responseData.measure_list.abc);
        done();
    });

});

PromiseResp внутри блока Before не выполняется.Поэтому переменная responseData не имеет данных и выдает контрольный пример неудачным.Я предполагаю, что есть некоторая проблема с асинхронным временем, но я не знаю, как ее решить, а также куда я могу поместить этот «process.exit (0)».Ниже приведен фактический вывод:

AC 1: This is suite one
I am in the before
    1) Test1
    2) Test2


  0 passing (7ms)
  2 failing

  1) AC 1: This is suite one
       Test1:
     TypeError: Cannot read property 'measure' of undefined
      at Context.it (QA/mockExecution.js:160:29)

  2) AC 1: This is suite one
       Test2:
     TypeError: Cannot read property 'measure' of undefined
      at Context.it (QA/mockExecution.js:167:29)

[process business logic and prints some logs here, i can't paste here]
finished analyzing all records
i am in the promise
npm ERR! Test failed.  See above for more details.

Я ожидаю вывод в следующей последовательности:

[process business logic and prints some logs here, I can't paste here]
finished analyzing all records
AC 1: This is suite one
    I am in the before
       I am in the promise
        1) Test1 passed
        2) Test2 paseed

Ответы [ 3 ]

0 голосов
/ 30 ноября 2018

Использование done вместе с обещаниями является антипаттерном, потому что это часто приводит к неправильному потоку управления, как в этом случае.Все основные среды тестирования уже поддерживают обещания, включая Mocha.

Если время ожидания по умолчанию (2 секунды) недостаточно велико для разрешения обещания, значение времени ожидания следует увеличить, например, как описано в в этом ответе , установив его для текущего набора тестов (this в describe контексте).Обратите внимание, что функция стрелки должна быть заменена обычной функцией для достижения контекста набора.

Это должно быть:

describe('AC 1: This is suite one', function () {
    this.timeout(60000);

    before(() => {
        return promiseResp.then((data) => {
            responseData = data;
        });
    });

    it('Test1', () => {            
       expect(responseData.measure.abc).not.toBe(responseData.measure_list.abc);
    });
    ...

Нет необходимости в catch для обещания;отклонения обещания будут обработаны рамками.Нет необходимости done в тестах;они синхронны.

0 голосов
/ 30 ноября 2018

В вашем it () нет никаких обещаний, поэтому нет никаких оснований для done (), но его следует вызывать внутри then (), поскольку он является обратным вызовом.

И в целом использование async / await понятнее.,Однако в before () это работает не очень хорошо.

Кроме того, функция 'function ()' предпочтительнее в description () для установки времени ожидания для тестов (вызов его как цепного метода никогда не работал на моем опыте)

describe('AC 1: This is suite one', function() {
  this.timeout(12000); //12 sec timeout for each it()
  before((done) => {
     promiseResp().then((data) => {
         responseData = data;
         done();
     })      
  })

  it('Test1', () => {
      expect(responseData.measure.abc).not.toBe(responseData.measure_list.abc);
  });

  it('Test2', () => {
      expect(responseData.measure.abc).not.toBe(responseData.measure_list.abc);
  });

});
0 голосов
/ 30 ноября 2018

Вам необходимо позвонить done в пределах вашего then и после того, как вы фактически присвоили responseData = data:

before((done) => {
  promiseResp.then((data) => {
    responseData = data;
    // Promise has resolved. Calling `done` to proceed to the `it` tests.
    done();
  })
  .catch((err) => {
    // Calling `done` with a truthy `err` argument, in case
    // the promise fails/rejects, to fail-early the test suite.
    done(err);
  })
})

, в противном случае before заканчивается преждевременно и переходит к следующемутесты, прежде чем обещание действительно разрешит и назначит вашу responseData переменную.

Вот рабочий пример с использованием ловушки before:

const expect = require('chai').expect

const getFooValue = () => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('foo')
    }, 500)
  })
}

describe('#getFooValue()', function () {
  let responseData

  before(done => {
    getFooValue().then(data => {
      responseData = data
      done()
    })
    .catch(err => {
      done(err)
    })
  })

  it('response has a value of foo', () => {
    expect(responseData).to.equal('foo');
  })

  it('response is a String', () => {
    expect(responseData).to.be.a('String');
  })
})

Что вы делаете сейчас:

  • Вы определяете Promise.
  • . Вы (преждевременно) звоните done, и Мокко продолжает выполнять it тесты.
  • itтесты выполняются, пока responseData все еще undefined.
  • Promise в before в конечном итоге разрешает и присваивает переменную responseData.

... но прив этот момент уже слишком поздноТесты уже запущены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...