La différence entre assert.equal et assert.deepEqual dans les tests Javascript avec Mocha?

92

J'utilise Mocha pour tester un petit module dans mon application Express.js. Dans ce module, une de mes fonctions renvoie un tableau. Je veux tester si le tableau est correct ou non pour une entrée donnée. Je le fais comme ceci:

suite('getWords', function(){
    test("getWords should return list of numbers", function() {
        var result = ['555', '867', '5309'];
        assert.equal(result, getWords('555-867-5309'));
    });
});

Lorsque cela s'exécute, j'obtiens l'erreur d'assertion suivante:

AssertionError: ["555","867","5309"] == ["555","867","5309"]

Cependant, lorsque je change mon test en un assert.deepEqual, le test réussit bien. Je me demandais si c'était un cas de ==vs ===, mais si j'entre

[1,2,3] === [1,2,3]

dans la ligne de commande node.js, j'obtiens toujours false.

Pourquoi les tableaux ne comparent-ils pas la façon dont les autres valeurs le font (par exemple 1 == 1)? et quelle est la différence entre assert.equal et assert.deepEqual?

mshell_lauren
la source

Réponses:

159

Pourquoi les tableaux ne comparent-ils pas les autres valeurs (par exemple 1 == 1)

Les nombres, les chaînes, les booléens nullet undefinedsont des valeurs et sont comparés comme vous pouvez vous y attendre. 1 == 1, 'a' == 'a'et ainsi de suite. La différence entre ===et ==dans le cas des valeurs est que vous ==tenterez d'effectuer d'abord la conversion de type, c'est pourquoi '1' == 1mais pas '1' === 1 .

Les tableaux, en revanche, sont des objets. ===et ==dans ce cas ne signifie pas que les opérandes sont sémantiquement égaux, mais qu'ils se réfèrent au même objet .

quelle est la difference entre assert.equal et assert.deepEqual?

assert.equalse comporte comme expliqué ci-dessus. Il échoue en fait si les arguments le sont !=, comme vous pouvez le voir dans la source . Ainsi, il échoue pour vos tableaux de chaînes de nombres car bien qu'ils soient essentiellement équivalents, ils ne sont pas le même objet.

L'égalité profonde (aka structurelle), d'autre part, ne teste pas si les opérandes sont le même objet, mais plutôt qu'ils sont équivalents. Dans un sens, on pourrait dire que cela force les objets à être comparés comme s'il s'agissait de valeurs.

var a = [1,2,3]  
var b = a              // As a and b both refer to the same object
a == b                 // this is true
a === b                // and this is also true

a = [1,2,3]            // here a and b have equivalent contents, but do not
b = [1,2,3]            // refer to the same Array object.
a == b                 // Thus this is false.

assert.deepEqual(a, b) // However this passes, as while a and b are not the 
                       // same object, they are still arrays containing 1, 2, 3

assert.deepEqual(1, 1) // Also passes when given equal values

var X = function() {}
a = new X
b = new X
a == b                 // false, not the same object
assert.deepEqual(a, b) // pass, both are unadorned X objects
b.foo = 'bar'
assert.deepEqual(a, b) // fail!
numéros1311407
la source
4
Grande explication de deepEqual(); pas vraiment quelque chose auquel vous pensez dans la comparaison jusqu'à ce que vous le rencontriez réellement.
brandonscript