2017-08-01 1 views
2

nous avons l'exemple de test de travail suivant:Pourquoi les fonctions qui lancent une exception ne passent-elles pas avec nom_fonction.should.throw (erreur)?

"use strict"; 

var should = require("chai").should(); 

var multiply = function(x, y) { 
    if (typeof x !== "number" || typeof y !== "number") { 
    throw new Error("x or y is not a number."); 
    } 
    else return x * y; 
}; 

describe("Multiply", function() { 
    it("should multiply properly when passed numbers", function() { 
    multiply(2, 4).should.equal(8); 
    }); 

    it("should throw when not passed numbers", function() { 
    (function() { 
     multiply(2, "4"); 
    }).should.throw(Error); 
    }); 
}); 

Il n'y a aucune explication sur la raison pour laquelle le second test doit être exécuté avec le hack

(function() { 
     multiply(2, "4"); 
    }).should.throw(Error); 

Si vous exécutez comme

it("should throw when not passed numbers", function() { 
     multiply(2, "4").should.throw(Error); 
    }); 

le test échoue

Multiply 
    ✓ should multiply properly when passed numbers 
    1) should throw when not passed numbers 

Mais en cours d'exécution de la fonction en tant que script de nœud régulier ne manque:

Error: x or y is not a number. 
    at multiply (/path/test/test.js:7:11) 

Je ne comprends pas pourquoi le should ne décrochez pas le fait qu'il jette l'erreur.

Quelle est la cause d'avoir besoin d'envelopper dans un appel anonyme function() { }? Est-ce que cela fait pour les tests qui s'exécutent de manière asynchrone, ou la portée ou quelque chose? Merci

Répondre

2

Chai est JavaScript courant, pas magique. Si vous avez une expression a().b.c() et a jette, c() ne peut pas l'attraper. c ne peut même pas fonctionner. Le moteur ne peut même pas savoir que cest, car a n'a pas retourné une valeur dont .b.c a pu être recherché; il a jeté une erreur à la place. Lorsque vous utilisez une fonction, vous avez un objet sur lequel rechercher .should, qui à son tour vous donne un objet sur lequel rechercher et appeler .throw.

Voilà pourquoi il ne peut pas faire, mais d'un point de vue de l'API, il n'y a rien de mal: .should.throw est juste une affirmation sur une fonction au lieu d'un appel de fonction.

Je vous recommande également d'utiliser expect de Chai, qui ne s'insère pas dans Object.prototype pour donner l'apparence de la magie.