Donc, je teste un composant qui repose sur un émetteur d'événement. Pour ce faire, j'ai trouvé une solution utilisant Promises avec 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();
});
});
Sur la console, j'obtiens un 'UnhandledPromiseRejectionWarning' même si la fonction de rejet est appelée car elle affiche instantanément le message 'AssertionError: Promise error'
(node: 25754) UnhandledPromiseRejectionWarning: Rejet de promesse non géré (identifiant de rejet: 2): AssertionError: Promise error: expected {Object (message, showDiff, ...)} to be false 1) should transition with the correct event
Et puis, après 2 secondes, je reçois
Erreur: dépassement du délai de 2000 ms. Assurez-vous que le rappel done () est appelé dans ce test.
Ce qui est encore plus étrange depuis que le rappel catch a été exécuté (je pense que pour une raison quelconque, l'échec d'assertion a empêché le reste de l'exécution)
Maintenant, ce qui est drôle, si je commente assert.isNotOk(error...)
le test, le test se déroule correctement sans aucun avertissement dans la console. Il «échoue» toujours dans le sens où il exécute la capture.
Mais encore, je ne peux pas comprendre ces erreurs avec promesse. Quelqu'un peut-il m'éclairer?
Réponses:
Le problème est causé par ceci:
Si l'assertion échoue, elle lèvera une erreur. Cette erreur entraînera de
done()
ne jamais être appelé, car le code s'est trompé avant elle. C'est ce qui cause le délai.Le «rejet de promesse non gérée» est également causé par l'assertion ayant échoué, car si une erreur est renvoyée dans un
catch()
gestionnaire et qu'il n'y a pas decatch()
gestionnaire suivant , l'erreur sera avalée (comme expliqué dans cet article ). L'UnhandledPromiseRejectionWarning
avertissement vous alerte sur ce fait.En général, si vous souhaitez tester du code basé sur des promesses dans Mocha, vous devez vous fier au fait que Mocha lui-même peut déjà gérer les promesses. Vous ne devriez pas utiliser
done()
, mais plutôt renvoyer une promesse de votre test. Mocha détectera alors toutes les erreurs lui-même.Comme ça:
la source
catch
gestionnaire devrait probablement être passé comme deuxième argument àthen
. Cependant, je ne suis pas tout à fait sûr de l'intention du PO, alors je l'ai laissé tel quel.done.fail('msg')
dans ce cas.J'ai eu cette erreur en stubbing avec sinon.
Le correctif consiste à utiliser le package npm sinon-as-promised lors de la résolution ou du rejet de promesses avec des stubs.
Au lieu de ...
Utilisation ...
Il existe également une méthode de résolution (notez le s à la fin).
Voir http://clarkdave.net/2016/09/node-v6-6-and-asynchronously-handled-promise-rejections
la source
Les bibliothèques d'assertions de Mocha fonctionnent en lançant une erreur si l'assertion n'était pas correcte. Lancer une erreur entraîne le rejet d'une promesse, même lorsqu'elle est lancée dans la fonction exécuteur fournie à la
catch
méthode.Dans le code ci-dessus, l'objet est
error
évaluétrue
ainsi la bibliothèque d'assertions renvoie une erreur ... qui n'est jamais interceptée. En raison de l'erreur, ladone
méthode n'est jamais appelée. Ledone
rappel de Mocha accepte ces erreurs, vous pouvez donc simplement terminer toutes les chaînes de promesses dans Mocha avec.then(done,done)
. Cela garantit que la méthode done est toujours appelée et que l'erreur sera signalée de la même manière que lorsque Mocha détecte l'erreur de l'assertion en code synchrone.Je donne crédit à cet article pour l'idée d'utiliser .then (done, done) lors du test des promesses dans Mocha.
la source
Pour ceux qui recherchent l'erreur / l'avertissement en
UnhandledPromiseRejectionWarning
dehors d'un environnement de test, cela pourrait probablement être dû au fait que personne dans le code ne s'occupe de l'erreur éventuelle dans une promesse:Par exemple, ce code affichera l'avertissement signalé dans cette question:
(node:XXXX) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Error reason!
et l'ajout de
.catch()
ou la gestion de l'erreur devrait résoudre l'avertissement / l'erreurOu en utilisant le deuxième paramètre dans la
then
fonctionla source
new Promise((resolve, reject) => { return reject('Error reason!'); })
mais en fonction,function test() { return new Promise((resolve, reject) => { return reject('Error reason!'); });}
donc à l'intérieur de la fonction, nous n'avons pas besoin d'utiliser.catch()
mais pour gérer avec succès les erreurs, il suffit de l'utiliser lors de l'appel de cette fonctiontest().catch(e => console.log(e))
ou de la version async /try { await test() } catch (e) { console.log(e) }
J'ai fait face à ce problème:
C'était mon erreur, je remplaçais l'
res
objet dansthen(function(res)
, donc changéres
en résultat et maintenant cela fonctionne.Faux
Correction
Code de service:
la source
Voici mon expérience avec E7 async / await :
Au cas où vous auriez un
async helperFunction()
appelé de votre test ... (une explicabilité avec leasync
mot-clé ES7 , je veux dire)→ assurez-vous que vous appelez ça comme
await helperFunction(whateverParams)
(enfin, ouais, naturellement, une fois que vous savez ...)Et pour que cela fonctionne (pour éviter `` attendre est un mot réservé ''), votre fonction de test doit avoir un marqueur asynchrone externe:
la source
await helperFunction(...)
. Uneasync
fonction renvoie une promesse. Vous pouvez simplement gérer la promesse retournée comme vous le feriez avec une fonction non marquéeasync
qui renvoie une promesse. Le but est de gérer la promesse, point final. Que la fonction soitasync
ou non n'a pas d'importance.await
est simplement l' une des multiples façons de gérer la promesse.UnhandledPromiseRejectionWarning
pour moi ... donc cette réponse.J'ai eu une expérience similaire avec Chai-Webdriver pour Selenium. J'ai ajouté
await
à l'assertion et cela a résolu le problème:Exemple utilisant Cucumberjs:
la source
J'ai résolu ce problème après avoir désinstallé webpack (problème react js).
la source