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