Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The difference between assert.equal and assert.deepEqual in Javascript testing with Mocha?

I'm using Mocha to test a small module in my Express.js application. In this module, one of my functions returns an array. I want to test whether or not the array is correct for a given input. I am doing so like this:

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

When this runs, I get the following assertion error:

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

However, when I change my test to an assert.deepEqual, the test passes fine. I was wondering if it was a case of == vs ===, but if I enter

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

into the node.js command line, I still get false.

Why do arrays not compare the way other values do (e.g. 1 == 1)? and what is the difference between assert.equal and assert.deepEqual?

like image 287
mshell_lauren Avatar asked Nov 05 '12 02:11

mshell_lauren


People also ask

What is assert deepEqual?

The assert. deepEqual() method tests if two objects, and their child objects, are equal, using the == operator. If the two objects are not equal, an assertion failure is being caused, and the program is terminated.


1 Answers

Why do arrays not compare the way other values do (e.g. 1==1)

Numbers, strings, booleans, null, and undefined are values, and are compared as you might expect. 1 == 1, 'a' == 'a', and so on. The difference between === and == in the case of values is that == will attempt to perform type conversion first, which is why '1' == 1 but not '1' === 1.

Arrays, on the other hand, are objects. === and == in this case do not signify that the operands are semantically equal, but that they refer to the same object.

what is the difference between assert.equal and assert.deepEqual?

assert.equal behaves as explained above. It actually fails if the arguments are !=, as you can see in the source. Thus it fails for your arrays of numbers strings because although they are essentially equivalent, they are not the same object.

Deep (aka structural) equality, on the other hand, does not test whether the operands are the same object, but rather that they're equivalent. In a sense, you could say it forces objects to be compared as though they're values.

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!
like image 167
numbers1311407 Avatar answered Oct 23 '22 10:10

numbers1311407