Разница между assert.equal и assert.deepEqual при тестировании Javascript с помощью Mocha?

94

Я использую Mocha для тестирования небольшого модуля в моем приложении Express.js. В этом модуле одна из моих функций возвращает массив. Я хочу проверить, подходит ли массив для данного ввода. Я делаю так:

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

Когда это выполняется, я получаю следующую ошибку утверждения:

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

Однако, когда я меняю свой тест на assert.deepEqual, тест проходит нормально. Мне было интересно, был ли это случай ==vs ===, но если я войду

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

в командную строку node.js, я все равно получаю false.

Почему массивы не сравниваются, как другие значения (например 1 == 1)? и в чем разница между assert.equal и assert.deepEqual?

mshell_lauren
источник

Ответы:

161

Почему массивы не сравниваются с другими значениями (например, 1 == 1)

Числа, строки, логические значения, nullи undefinedявляются значениями и сравниваются, как и следовало ожидать. 1 == 1, 'a' == 'a'и так далее. Разница между значениями ===и ==в случае значений заключается в том, что ==сначала будет предпринята попытка выполнить преобразование типа, поэтому, '1' == 1но нет '1' === 1 .

С другой стороны, массивы - это объекты. ===и ==в этом случае не означают, что операнды семантически равны, но что они относятся к одному и тому же объекту .

в чем разница между assert.equal и assert.deepEqual?

assert.equalведет себя как описано выше. На самом деле это не удается, если аргументы есть !=, как вы можете видеть в источнике . Таким образом, он не работает для ваших массивов строк чисел, потому что, хотя они по существу эквивалентны, они не являются одним и тем же объектом.

С другой стороны, глубокое (также известное как структурное) равенство не проверяет, являются ли операнды одним и тем же объектом, а проверяет их эквивалентность. В некотором смысле можно сказать, что он заставляет сравнивать объекты, как если бы они были ценностями.

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!
числа1311407
источник
4
Отличное объяснение deepEqual(); на самом деле это не то, о чем вы думаете при сравнении, пока вы действительно не столкнетесь с этим.
brandonscript 06