Entonces, estoy probando un componente que se basa en un emisor de eventos. Para hacerlo, se me ocurrió una solución usando Promesas con 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();
});
});
En la consola, obtengo un 'UnhandledPromiseRejectionWarning' a pesar de que se llama a la función de rechazo, ya que muestra instantáneamente el mensaje 'AssertionError: Promise error'
(nodo: 25754) UnhandledPromiseRejectionWarning: Rechazo de promesa no controlado (id de rechazo: 2): Error de promesa: Error de promesa: se espera que {Object (message, showDiff, ...)} sea falso 1) debe hacer la transición con el evento correcto
Y luego, después de 2 segundos me sale
Error: se excedió el tiempo de espera de 2000 ms. Asegúrese de que se llame a la devolución de llamada done () en esta prueba.
Lo cual es aún más extraño ya que se ejecutó la devolución de llamada catch (creo que por alguna razón el fallo de afirmación impidió el resto de la ejecución)
Ahora lo curioso, si comento que assert.isNotOk(error...)
la prueba funciona bien sin ninguna advertencia en la consola. Todavía 'falla' en el sentido de que ejecuta la captura.
Pero aún así, no puedo entender estos errores con promesa. ¿Alguien puede iluminarme?
Respuestas:
El problema es causado por esto:
Si la afirmación falla, arrojará un error. Este error hará que
done()
nunca se vuelva a llamar, porque el código erró antes. Eso es lo que causa el tiempo de espera.El "rechazo de la promesa no manejada" también es causado por la afirmación fallida, porque si se arroja un error en un
catch()
controlador y no hay uncatch()
controlador posterior , el error se tragará (como se explica en este artículo ). losUnhandledPromiseRejectionWarning
advertencia lo alerta sobre este hecho.En general, si desea probar el código basado en promesas en Mocha, debe confiar en el hecho de que Mocha ya puede manejar las promesas. No debe usar
done()
, sino devolver una promesa de su prueba. Mocha entonces detectará cualquier error por sí mismo.Me gusta esto:
fuente
catch
controlador probablemente debería pasarse como segundo argumento athen
. Sin embargo, no estoy completamente seguro de cuál era la intención del OP, así que lo dejé como está.done.fail('msg')
en este caso.Recibí este error al tropezar con sinon.
La solución es usar el paquete npm sinon-as-prometido al resolver o rechazar promesas con apéndices.
En vez de ...
Utilizar ...
También hay un método de resolución (tenga en cuenta la s al final).
Ver http://clarkdave.net/2016/09/node-v6-6-and-asynchronously-handled-promise-rejections
fuente
Las bibliotecas de aserciones en Mocha funcionan arrojando un error si la aserción no era correcta. Lanzar un error da como resultado una promesa rechazada, incluso cuando se lanza en la función ejecutora proporcionada al
catch
método.En el código anterior, el
error
objetado se evalúa paratrue
que la biblioteca de aserciones arroje un error ... que nunca se detecta. Como resultado del errordone
, nunca se llama al método. Ladone
devolución de llamada de Mocha acepta estos errores, por lo que simplemente puede finalizar todas las cadenas de promesa en Mocha con.then(done,done)
. Esto garantiza que siempre se llame al método realizado y que el error se informe de la misma manera que cuando Mocha detecta el error de la aserción en código síncrono.Doy crédito a este artículo por la idea de usar .then (hecho, hecho) al probar promesas en Mocha.
fuente
Para aquellos que buscan el error / advertencia
UnhandledPromiseRejectionWarning
fuera de un entorno de prueba, podría ser probablemente porque nadie en el código se está ocupando del eventual error en una promesa:Por ejemplo, este código mostrará la advertencia informada en esta pregunta:
(node:XXXX) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Error reason!
y agregar
.catch()
o manejar el error debería resolver la advertencia / errorO usando el segundo parámetro en la
then
funciónfuente
new Promise((resolve, reject) => { return reject('Error reason!'); })
sino en función,function test() { return new Promise((resolve, reject) => { return reject('Error reason!'); });}
por lo que no es necesario usar la función interna,.catch()
sino que para manejar con éxito los errores, es suficiente para usar cuando se llama a esa funcióntest().catch(e => console.log(e))
o versión asíncrona / esperatry { await test() } catch (e) { console.log(e) }
Me enfrenté a este problema:
Fue mi error, estaba reemplazando el
res
objetothen(function(res)
, así que cambiéres
al resultado y ahora está funcionando.Incorrecto
Corrección
Código de servicio:
fuente
Aquí está mi experiencia con E7 async / await :
En caso de que
async helperFunction()
reciba una llamada de su prueba ... (una de ellas con el ES7async
palabra clave , quiero decir)→ asegúrese de llamarlo como
await helperFunction(whateverParams)
así (bueno, sí, naturalmente, una vez que sepa ...)Y para que eso funcione (para evitar 'esperar es una palabra reservada'), su función de prueba debe tener un marcador asíncrono externo:
fuente
await helperFunction(...)
. Unaasync
función devuelve una promesa. Puede manejar la promesa devuelta como lo haría en una función no marcadaasync
que devuelve una promesa. El punto es manejar la promesa, punto. Si la función esasync
o no, no importa.await
es simplemente una de las múltiples formas de manejar la promesa.UnhandledPromiseRejectionWarning
me causó eso ... así que esta respuesta.Tuve una experiencia similar con Chai-Webdriver para Selenium. Agregué
await
a la afirmación y solucionó el problema:Ejemplo usando Cucumberjs:
fuente
Resolví este problema después de desinstalar webpack (reaccionar problema js).
fuente