En utilisant Mocha, je tente de tester si un constructeur génère une erreur. Je n'ai pas été capable de faire cela en utilisant la syntaxe expect, alors j'aimerais faire ce qui suit:
it('should throw exception when instantiated', function() {
try {
new ErrorThrowingObject();
// Force the test to fail since error wasn't thrown
}
catch (error) {
// Constructor threw Error, so test succeeded.
}
}
Est-ce possible?
Vous pouvez essayer d’utiliser la construction de Chaithrow
. Par exemple:
expect(Constructor).to.throw(Error);
Utiliser la bibliothèque should.js avec should.fail
var should = require('should')
it('should fail', function(done) {
try {
new ErrorThrowingObject();
// Force the test to fail since error wasn't thrown
should.fail('no error was thrown when it should have been')
}
catch (error) {
// Constructor threw Error, so test succeeded.
done();
}
});
Alternative vous pouvez utiliser le devrait throwError
(function(){
throw new Error('failed to baz');
}).should.throwError(/^fail.*/)
Et avec chai en utilisant le throw api
var expect = require('chai').expect
it('should fail', function(done) {
function throwsWithNoArgs() {
var args {} // optional arguments here
new ErrorThrowingObject(args)
}
expect(throwsWithNoArgs).to.throw
done()
});
2017 répondez si vous avez besoin de le faire avec un code asynchrone : using wait et ne nécessitant aucune autre bibliothèque .
it('Returns a correct error response when making a broken order', async function(){
this.timeout(5 * 1000);
var badOrder = {}
try {
var result = await foo.newOrder(badOrder)
// The line will only be hit if no error is thrown above!
throw new Error(`Expected an error and didn't get one!`)
} catch(err) {
var expected = `Missing required field`
assert.equal(err.message, expected)
}
});
Notez que l'affiche ne faisait que du code de synchronisation, mais je m'attends à ce que beaucoup de personnes utilisant async soient dirigées ici par le titre de la question!
Mocha utilise par défaut Assert de node.js ( https://nodejs.org/api/assert.html ). Vous n'avez besoin d'aucune bibliothèque externe pour vérifier si une méthode génère une erreur.
Assert a une méthode - assert.throws
, elle a trois paramètres, mais seulement deux sont vraiment importants ici:
Imaginons que vous ayez une fonction appelée sendMessage(message)
qui lève une erreur lorsque le paramètre message n'est pas défini. Code de fonction:
function sendMessage(message) {
if (!message || typeof message !== 'string') {
throw new Error('Wrong message');
}
// rest of function
}
Ok, donc pour le tester, vous avez besoin d’une fonction supplémentaire pour couvrir les entrées. Pourquoi? Parce que assert.throws
ne donne aucune possibilité de passer des paramètres à la fonction à tester.
Donc au lieu de
// WRONG
assert.throws(sendMessage, Error); // THIS IS WRONG! NO POSSIBILITY TO PASS ANYTHING
vous devez créer une fonction anonyme:
// CORRECT
assert.throws(() => {
sendMessage(12); // usage of wanted function with test parameters
}, Error)
Pouvez-vous voir la différence? Au lieu de passer directement de fonction à un autre, j’ai mis l’appel de fonction dans une fonction anonyme afin de l’appeler avec une entrée préparée.
Qu'en est-il du deuxième paramètre. Cela dépend de quel type d'erreur doit être généré, dans l'exemple ci-dessus, un objet Error
a été lancé, j'ai donc dû y mettre Error
. À la suite de cette action, assert.throws
compare si l'objet jeté est un objet du même type. Si au lieu de Error
quelque chose de différent sera lancé, cette partie doit être modifiée. Par exemple, au lieu de Error
, je jetterai une valeur de type String
.
function sendMessage(message) {
if (!message || typeof message !== 'string') {
throw 'Wrong message'; // change to String
}
// rest of function
}
Maintenant l'appel d'essai
assert.throws(() => {
sendMessage(12); // usage of wanted function with test parameters
}, (err) => err === 'Wrong message')
Au lieu de Error
dans le deuxième paramètre, j'ai utilisé la fonction de comparaison afin de comparer l'erreur renvoyée à l'attente.
La réponse acceptée par MarkJ est la voie à suivre et beaucoup plus simple que d’autres ici.
function fn(arg) {
if (typeof arg !== 'string')
throw TypeError('Must be an string')
return { arg: arg }
}
describe('#fn', function () {
it('empty arg throw error', function () {
expect(function () {
new fn()
}).to.throw(TypeError)
})
it('non-string arg throw error', function () {
expect(function () {
new fn(2)
}).to.throw(TypeError)
})
it('string arg return instance { arg: <arg> }', function () {
expect(new fn('str').arg).to.be.equal('str')
})
})
Si vous ne voulez pas encombrer de sources dans le paramètre expect
, ou si vous avez beaucoup d'arguments à transmettre et que cela devient vraiment moche, vous pouvez toujours le faire avec la syntaxe d'origine, en utilisant les arguments done
. fourni (mais a été ignoré à l'origine):
it('should throw exception when instantiated', function(done: Done) {
try {
new ErrorThrowingObject();
done(new Error(`Force the test to fail since error wasn't thrown`));
}
catch (error) {
// Constructor threw Error, so test succeeded.
done();
}
}
Puisque vous utilisez done
ici, cela vous permet d’exécuter du code arbitraire au-dessus de celui-ci dans try
, puis de spécifier exactement où vous voulez enregistrer l’erreur dans votre source.
Normalement, une personne peut être tentée par throw
ou assert(false)
, mais celles-ci seront toutes deux capturées par la catch
de la try
et vous obligeront à effectuer une méta-vérification pour déterminer si l'erreur que vous avez détectée était l'erreur attendue de votre test ou si c'était la détermination finale que votre test a échoué. C'est juste un gâchis.
Si vous utilisez should.js vous pouvez faire (new ErrorThrowingObject).should.throw('Option Error Text or Regular Expression here')
Si vous ne voulez pas une bibliothèque séparée, vous pouvez aussi faire quelque chose comme ça:
it('should do whatever', function(done) {
try {
...
} catch(error) {
done();
}
}
De cette façon, vous savez que l'erreur est interceptée si le test se termine. Sinon, vous obtiendrez une erreur de délai d'attente.
Avec Chai throw
(ES2016)
http://chaijs.com/api/bdd/#method_throw
Pour plus de clarté ... Cela fonctionne
it('Should fail if ...', done => {
let ret = () => {
MyModule.myFunction(myArg);
};
expect(ret).to.throw();
done();
});
Ça ne marche pas
it('Should fail if ...', done => {
let ret = MyModule.myFunction(myArg);
expect(ret).to.throw();
done();
});