La differenza tra assert.equal e assert.deepEqual nei test Javascript con Mocha?


92

Sto usando Mocha per testare un piccolo modulo nella mia applicazione Express.js. In questo modulo, una delle mie funzioni restituisce un array. Voglio verificare se l'array è corretto o meno per un dato input. Lo sto facendo in questo modo:

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

Quando viene eseguito, ottengo il seguente errore di asserzione:

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

Tuttavia, quando cambio il mio test in un assert.deepEqual, il test viene superato correttamente. Mi chiedevo se fosse un caso di ==vs ===, ma se entro

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

nella riga di comando node.js, ottengo ancora false.

Perché gli array non si confrontano come fanno gli altri valori (ad es. 1 == 1)? e qual è la differenza tra assert.equal e assert.deepEqual?

Risposte:


159

Perché gli array non si confrontano come fanno gli altri valori (es. 1 == 1)

Numeri, stringhe, valori booleani nulle undefinedsono valori e vengono confrontati come ci si potrebbe aspettare. 1 == 1, 'a' == 'a'e così via. La differenza tra ===e ==nel caso dei valori è che ==tenterà di eseguire prima la conversione del tipo, motivo per cui '1' == 1ma non '1' === 1 .

Gli array, d'altra parte, sono oggetti. ===e ==in questo caso non significa che gli operandi sono semanticamente uguali, ma che si riferiscono allo stesso oggetto .

qual è la differenza tra assert.equal e assert.deepEqual?

assert.equalsi comporta come spiegato sopra. In realtà fallisce se gli argomenti sono !=, come puoi vedere nel codice sorgente . Quindi fallisce per i tuoi array di stringhe di numeri perché sebbene siano essenzialmente equivalenti, non sono lo stesso oggetto.

L'uguaglianza profonda (ovvero strutturale), d'altra parte, non verifica se gli operandi sono lo stesso oggetto, ma piuttosto se sono equivalenti. In un certo senso, potresti dire che costringe gli oggetti a essere confrontati come se fossero valori.

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!

4
Ottima spiegazione di deepEqual(); non proprio qualcosa a cui pensi nel confronto fino a quando non lo incontri davvero.
brandonscript
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.