A diferença entre assert.equal e assert.deepEqual em testes de Javascript com Mocha?

91

Estou usando o Mocha para testar um pequeno módulo em meu aplicativo Express.js. Neste módulo, uma das minhas funções retorna um array. Quero testar se a matriz está correta ou não para uma determinada entrada. Estou fazendo assim:

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

Quando isso é executado, recebo o seguinte erro de declaração:

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

No entanto, quando eu mudo meu teste para um assert.deepEqual, ele passa bem. Eu queria saber se era um caso de ==vs ===, mas se eu entrar

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

na linha de comando node.js, ainda consigo falso.

Por que os arrays não comparam a maneira como outros valores o fazem (por exemplo 1 == 1)? e qual é a diferença entre assert.equal e assert.deepEqual?

mshell_lauren
fonte

Respostas:

158

Por que as matrizes não comparam a forma como os outros valores o fazem (por exemplo, 1 == 1)

Números, strings, booleanos, nulle undefinedsão valores e são comparados conforme o esperado. 1 == 1, 'a' == 'a'e assim por diante. A diferença entre ===e ==no caso de valores é que ==tentará realizar a conversão de tipo primeiro, que é o motivo, '1' == 1mas não '1' === 1 .

Arrays, por outro lado, são objetos. ===e ==, neste caso, não significa que os operandos sejam semanticamente iguais, mas que se referem ao mesmo objeto .

qual é a diferença entre assert.equal e assert.deepEqual?

assert.equalse comporta conforme explicado acima. Na verdade, ele falha se os argumentos forem !=, como você pode ver na fonte . Portanto, falha para seus arrays de strings de números porque, embora sejam essencialmente equivalentes, não são o mesmo objeto.

A igualdade profunda (também conhecida como estrutural), por outro lado, não testa se os operandos são o mesmo objeto, mas sim se são equivalentes. Em certo sentido, você poderia dizer que força os objetos a serem comparados como se fossem valores.

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!
números 1311407
fonte
4
Ótima explicação de deepEqual(); não é realmente algo em que você pensa na comparação até que realmente encontre.
brandonscript de