javascript - with - using chai nodejs




NodeJS UnhandledPromiseRejectionWarning (5)

Aqui está minha experiência com o E7 async / await :

Caso você tenha um async helperFunction() chamado a partir do seu teste ... (um explicilty com a palavra async chave async do ES7, quero dizer)

→ certifique-se, você chama isso de await helperFunction(whateverParams) (bem, sim, naturalmente, uma vez que você sabe ...)

E para que isso funcione (para evitar que 'await seja uma palavra reservada'), sua função de teste deve ter um marcador assíncrono externo:

it('my test', async () => { ...

Então, estou testando um componente que depende de um emissor de eventos. Para fazer isso, criei uma solução usando o Promises with Mocha + Chai:

it('should transition with the correct event', (done) => {
  const cFSM = new CharacterFSM({}, emitter, transitions);
  let timeout = null;
  let resolved = false;
  new Promise((resolve, reject) => {
    emitter.once('action', resolve);
    emitter.emit('done', {});
    timeout = setTimeout(() => {
    if (!resolved) {
      reject('Timedout!');
    }
    clearTimeout(timeout);
  }, 100);
}).then(((state) => {
      resolved = true;
      assert(state.action === 'DONE', 'should change state');
      done();
    }))
    .catch((error) => {
      assert.isNotOk(error,'Promise error');
      done();
    });
  });
});

No console, estou recebendo um 'UnhandledPromiseRejectionWarning' mesmo que a função de rejeição esteja sendo chamada, pois mostra instantaneamente a mensagem 'AssertionError: Promise error'

(node: 25754) UnhandledPromiseRejectionWarning: Rejeição de promessa não tratada (id de rejeição: 2): AssertionError: Erro de promessa: esperado {Object (message, showDiff, ...)} para ser falso 1) deve fazer a transição com o evento correto

E então, depois de 2 segundos eu recebo

Erro: tempo limite de 2000 ms excedido. Certifique-se de que o retorno de chamada done () esteja sendo chamado neste teste.

O que é ainda mais estranho desde que o callback de captura foi executado (acho que por algum motivo a falha de declaração impediu o restante da execução)

Agora, o engraçado, se eu comentar o assert.isNotOk(error...) o teste é executado sem qualquer aviso no console. Ainda assim, "falha" no sentido de que executa a captura.
Mas ainda assim, não consigo entender esses erros com promessa. Alguém pode me esclarecer?


As bibliotecas de asserção no Mocha funcionam enviando um erro se a asserção não estiver correta. Lançar um erro resulta em uma promessa rejeitada, mesmo quando lançada na função executora fornecida ao método catch .

.catch((error) => {
  assert.isNotOk(error,'Promise error');
  done();
});

No código acima, o error objetivado é avaliado como true portanto, a biblioteca de asserções gera um erro ... que nunca é detectado. Como resultado do erro, o método done nunca é chamado. O callback de Mocha aceita esses erros, então você pode simplesmente terminar todas as cadeias de promessas em Mocha com .then(done,done) . Isso garante que o método feito seja sempre chamado e que o erro seja relatado da mesma maneira que quando o Mocha captura o erro da asserção no código síncrono.

it('should transition with the correct event', (done) => {
  const cFSM = new CharacterFSM({}, emitter, transitions);
  let timeout = null;
  let resolved = false;
  new Promise((resolve, reject) => {
    emitter.once('action', resolve);
    emitter.emit('done', {});
    timeout = setTimeout(() => {
      if (!resolved) {
        reject('Timedout!');
      }
      clearTimeout(timeout);
    }, 100);
  }).then(((state) => {
    resolved = true;
    assert(state.action === 'DONE', 'should change state');
  })).then(done,done);
});

Eu dou crédito a este artigo pela ideia de usar o then (done, done) quando testando promessas no Mocha.


Eu recebi este erro quando toco com sinon.

A correção é usar o pacote npm sinon-as-promised ao resolver ou rejeitar promessas com stubs.

Ao invés de ...

sinon.stub(Database, 'connect').returns(Promise.reject( Error('oops') ))

Usar ...

require('sinon-as-promised');
sinon.stub(Database, 'connect').rejects(Error('oops'));

Há também um método resolve (observe os s no final).

Veja http://clarkdave.net/2016/09/node-v6-6-and-asynchronously-handled-promise-rejections


Eu resolvi esse problema depois de desinstalar o webpack (reagir js problem).

sudo uninstall webpack

Para aqueles que estão procurando o erro / aviso UnhandledPromiseRejectionWarning fora de um ambiente de teste, pode ser provavelmente porque ninguém no código está cuidando do eventual erro em uma promessa:

Por exemplo, esse código mostrará o aviso relatado nesta pergunta:

new Promise((resolve, reject) => {
  return reject('Error reason!');
});

(node:XXXX) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Error reason!

e adicionar o .catch() ou manipular o erro deve resolver o aviso / erro

new Promise((resolve, reject) => {
  return reject('Error reason!');
}).catch(() => { /* do whatever you want here */ });

Ou usando o segundo parâmetro na função then

new Promise((resolve, reject) => {
  return reject('Error reason!');
}).then(null, () => { /* do whatever you want here */ });




chai