J'ai des problèmes à faire en sorte que expect.to.throw
de Chai fonctionne dans un test de mon application node.js. Le test échoue sans cesse sur l'erreur renvoyée, mais si j'emballe le scénario de test pour essayer d'attraper et d'affirmer l'erreur interceptée, cela fonctionne.
Est-ce que expect.to.throw
ne fonctionne pas comme je le pense ou non?
it('should throw an error if you try to get an undefined property', function (done) {
var params = { a: 'test', b: 'test', c: 'test' };
var model = new TestModel(MOCK_REQUEST, params);
// neither of these work
expect(model.get('z')).to.throw('Property does not exist in model schema.');
expect(model.get('z')).to.throw(new Error('Property does not exist in model schema.'));
// this works
try {
model.get('z');
}
catch(err) {
expect(err).to.eql(new Error('Property does not exist in model schema.'));
}
done();
});
L'échec:
19 passing (25ms)
1 failing
1) Model Base should throw an error if you try to get an undefined property:
Error: Property does not exist in model schema.
Vous devez passer une fonction à expect
. Comme ça:
expect(model.get.bind(model, 'z')).to.throw('Property does not exist in model schema.');
expect(model.get.bind(model, 'z')).to.throw(new Error('Property does not exist in model schema.'));
De la façon dont vous le faites, vous passez à expect
le résultat de l'appel de model.get('z')
. Mais pour tester si quelque chose est jeté, vous devez passer une fonction à expect
, qui expect
s’appellera elle-même. La méthode bind
utilisée ci-dessus crée une nouvelle fonction qui, lorsqu'elle est appelée, appelle model.get
avec this
définie sur la valeur de model
et sur le premier argument défini sur 'z'
. .
Une bonne explication de bind
peut être trouvée ici .
Comme cette réponse dit , vous pouvez aussi simplement envelopper votre code dans une fonction anonyme comme celle-ci:
expect(function(){
model.get('z');
}).to.throw('Property does not exist in model schema.');
Et si vous utilisez déjà ES6/ES2015, vous pouvez également utiliser une fonction de flèche. C'est fondamentalement la même chose que d'utiliser une fonction anonyme normale mais plus courte.
expect(() => model.get('z')).to.throw('Property does not exist in model schema.');
Cette question a beaucoup, beaucoup de doublons, y compris des questions ne mentionnant pas la bibliothèque d'affirmations Chai. Voici les bases rassemblées ensemble:
L'assertion doit appeler la fonction au lieu de l'évaluation immédiate.
assert.throws(x.y.z);
// FAIL. x.y.z throws an exception, which immediately exits the
// enclosing block, so assert.throw() not called.
assert.throws(()=>x.y.z);
// assert.throw() is called with a function, which only throws
// when assert.throw executes the function.
assert.throws(function () { x.y.z });
// if you cannot use ES6 at work
function badReference() { x.y.z }; assert.throws(badReference);
// for the verbose
assert.throws(()=>model.get(z));
// the specific example given.
homegrownAssertThrows(model.get, z);
// a style common in Python, but not in JavaScript
Vous pouvez vérifier des erreurs spécifiques en utilisant n'importe quelle bibliothèque d'assertions:
assert.throws(() => x.y.z);
assert.throws(() => x.y.z, ReferenceError);
assert.throws(() => x.y.z, ReferenceError, /is not defined/);
assert.throws(() => x.y.z, /is not defined/);
assert.doesNotThrow(() => 42);
assert.throws(() => x.y.z, Error);
assert.throws(() => model.get.z, /Property does not exist in model schema./)
should.throws(() => x.y.z);
should.throws(() => x.y.z, ReferenceError);
should.throws(() => x.y.z, ReferenceError, /is not defined/);
should.throws(() => x.y.z, /is not defined/);
should.doesNotThrow(() => 42);
should.throws(() => x.y.z, Error);
should.throws(() => model.get.z, /Property does not exist in model schema./)
expect(() => x.y.z).to.throw();
expect(() => x.y.z).to.throw(ReferenceError);
expect(() => x.y.z).to.throw(ReferenceError, /is not defined/);
expect(() => x.y.z).to.throw(/is not defined/);
expect(() => 42).not.to.throw();
expect(() => x.y.z).to.throw(Error);
expect(() => model.get.z).to.throw(/Property does not exist in model schema./);
Vous devez gérer les exceptions qui "échappent" au test
it('should handle escaped errors', function () {
try {
expect(() => x.y.z).not.to.throw(RangeError);
} catch (err) {
expect(err).to.be.a(ReferenceError);
}
});
Cela peut paraître déroutant au début. Comme sur un vélo, il suffit de cliquer pour toujours.
exemples de doc ...;)
parce que vous vous appuyez sur ce contexte :
vous devez utiliser l'une de ces options:
lie le contexte
// wrap the method or function call inside of another function
expect(function () { cat.meow(); }).to.throw(); // Function expression
expect(() => cat.meow()).to.throw(); // ES6 arrow function
// bind the context
expect(cat.meow.bind(cat)).to.throw(); // Bind
Une autre implémentation possible, plus lourde que la solution .bind (), mais qui permet de préciser le fait que expect () nécessite une fonction qui fournit un contexte this
à la fonction couverte, vous pouvez utiliser un call()
, par exemple,
expect(function() {model.get.call(model, 'z');}).to.throw('...');