Как справиться с асинхронным тестом в Мокко?

У меня есть функция обработчика событий, которая принимает некоторые данные о событиях и функцию обратного вызова в качестве входных данных.

Этот обработчик событий использует обещание, чтобы выполнить свою работу:

function myHandler(event, callback) {
  somePromise(event).then((result) => {
    if (result.Error) {
      callback(error);
    } else {
      callback(null, result.SuccessData);
    }
  });
}

У меня есть следующий код для проверки обработчика:

it('test handler', function(done) {
  let event = {...};
  myHandler(event, function(error, success) {
    expect(success).to.not.be.null;
    expect(error).to.be.null;
    expect(success.member).to.be.equal('expected');
    done();
  }
});

При запуске этого теста я получаю эту ошибку:

(node:3508) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): AssertionError: expected 'unexpected' to equal 'expected'

и конец всех тестов:

Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

но все же испытание все еще проходит...

Почему эта ошибка происходит в то время как done() функция называется?

2 ответа

Решение

Оберните ваш тест в обещание, которое отклоняется, если утверждение не выполняется.

it('test handler', () => {
  let event = {...}
  return new Promise((resolve, reject) => {
    myHandler(event, (error, success) => {
      try {
        expect(success).to.not.be.null;
        expect(error).to.be.null;
        expect(success.member).to.be.equal('expected');
        resolve();
      } catch (err) {
        reject(err);
      }
    });
  });
});

Вы используете Обещания. Вы можете вернуть свое обещание без использования done, как это:

// Note the absence of the done callback here
it('test handler', function() {
  let event = {...};
  return myHandler(event, function(error, success) {
    expect(success).to.not.be.null;
    expect(error).to.be.null;
    expect(success.member).to.be.equal('expected');
  }
});

Или используйте Чай как обещано:

it('test handler', function(done) {
  let event = {...};
  myHandler(event, function(error, success) {
    expect(success).to.not.be.null;
    expect(error).to.be.null;
    expect(success.member).to.be.equal('expected');
  }.should.notify(done)
});

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

Другие вопросы по тегам