Reputation: 179
Hey so I was playing around with Jasmine today and I wrote this simple Person object
function Person() {}
Person.prototype.name = "Alex";
Person.prototype.age = 24;
Here's my Spec test
describe("Person", function() {
var someone = new Person();
it('should be equal to other people', function() {
var another = {
name: "Joe",
age: 25,
};
expect(someone).toEqual(another);
});
});
Yet it fails with Expected { } to equal { name : 'Alex', age : 24 } Shouldn't Jasmine's toEqual matcher work for objects? Am I missing something here?
Thanks!
Upvotes: 2
Views: 1531
Reputation: 11970
If you walk through the source code, you will see that Jasmine's toEqual
matcher ultimately uses hasOwnProperty
when comparing objects. You can see this in this snippet of code in matchersUtil.js.
function has(obj, key) {
return obj.hasOwnProperty(key);
}
That function is used in the eq
function in the same file in this way:
// Deep compare objects.
for (var key in a) {
if (has(a, key)) {
// Count the expected number of properties.
size++;
// Deep compare each member.
if (!(result = has(b, key) && eq(a[key], b[key], aStack, bStack, customTesters))) { break; }
}
}
...annnnd the eq
function is used by toEqual.js
matcher when util.equals
is called.
So, because the toEqual
matcher uses hasOwnProperty
, when it does a comparison it will not "see" properties up the prototype chain but only properties on the immediate object.
One note: using your code, I got a slightly but significantly different result for the test:
Expected { } to equal {name: 'Joe', age: 25 }
That lines up with Jasmine's usage of hasOwnProperty
making someone
appear empty when prototype properties are ignored.
Upvotes: 3