简体   繁体   中英

Comparing objects using Jasmine Specs

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!

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM