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


91

Я використовую 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"]

Однак, коли я міняю свій тест на an assert.deepEqual, тест проходить нормально. Мені було цікаво, чи це був випадок ==проти ===, але якщо я вступлю

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

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

Чому масиви не порівнюють так, як інші значення (наприклад 1 == 1)? і в чому різниця між assert.equal та assert.deepEqual?

Відповіді:


158

Чому масиви не порівнюють так, як інші значення (наприклад, 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!

4
Чудове пояснення deepEqual(); насправді не те, про що ви думаєте в порівнянні, поки насправді не натрапите на це.
brandonscript
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.