ความแตกต่างระหว่าง 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"]

อย่างไรก็ตามเมื่อฉันเปลี่ยนการทดสอบเป็น an assert.deepEqualการทดสอบก็ผ่านไปได้ด้วยดี ฉันสงสัยว่ามันเป็นกรณีของ==vs ===แต่ถ้าฉันเข้า

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

ในบรรทัดคำสั่ง node.js ฉันยังคงได้รับเท็จ

เหตุใดอาร์เรย์จึงไม่เปรียบเทียบกับค่าอื่น ๆ (เช่น1 == 1) และอะไรคือความแตกต่างระหว่าง assert.equal และ assert.deepEqual?

คำตอบ:


161

เหตุใดอาร์เรย์จึงไม่เปรียบเทียบกับค่าอื่น ๆ (เช่น 1 == 1)

ตัวเลขสตริงบูลีนnullและundefinedเป็นค่าและมีการเปรียบเทียบตามที่คุณคาดหวัง 1 == 1, 'a' == 'a'และอื่น ๆ ความแตกต่างระหว่าง===และ==ในกรณีของค่าคือการที่==จะพยายามที่จะดำเนินการแปลงชนิดแรกซึ่งเป็นเหตุผลที่'1' == 1แต่ไม่ได้ '1' === 1

ในทางกลับกันอาร์เรย์เป็นวัตถุ ===และ==ในกรณีนี้ไม่ได้มีความหมายว่าตัวถูกดำเนินการที่มีความหมายเท่ากัน แต่ที่พวกเขาหมายถึงวัตถุเดียวกัน

assert.equal และ assert.deepEqual ต่างกันอย่างไร

assert.equalทำงานตามที่อธิบายไว้ข้างต้น มันจริงล้มเหลวหากข้อโต้แย้งที่มี!=ในขณะที่คุณสามารถดูในแหล่งที่มา ดังนั้นจึงล้มเหลวสำหรับอาร์เรย์ของสตริงตัวเลขของคุณเนื่องจากแม้ว่าจะเทียบเท่ากันเป็นหลัก แต่ก็ไม่ใช่วัตถุเดียวกัน

ในทางกลับกันความเสมอภาคเชิงลึก (aka โครงสร้าง) ไม่ได้ทดสอบว่าตัวถูกดำเนินการเป็นวัตถุเดียวกันหรือไม่ แต่จะเทียบเท่ากัน ในแง่หนึ่งคุณสามารถพูดได้ว่ามันบังคับให้เปรียบเทียบวัตถุราวกับว่าเป็นค่านิยม

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.