toEqual using objects with functions

4,106 views
Skip to first unread message

Matt Hughes

unread,
Jan 15, 2014, 9:33:14 AM1/15/14
to jasmi...@googlegroups.com
I want to be able to compare two instances of the same class, but only the data:

    it("two objects with same data should be equal", function() {
      function Person(name, age) {
         this.name = name;
         this.age = age;
         this.isOldEnoughToVote = function() { return age > 18; }
      }

      var matt1 = new Person('Matt', 21);
      var matt2 = new Person('Matt', 21);

      expect(matt1).toEqual(matt2);
    });


If I compare two instances with the same data, Jasmine says they are not equal:

     Tests Expected { name : 'Matt', age : 21, isOldEnoughToVote : Function } to equal { name : 'Matt', age : 21, isOldEnoughToVote : Function }.
    Error: Expected { name : 'Matt', age : 21, isOldEnoughToVote : Function } to equal { name : 'Matt', age : 21, isOldEnoughToVote : Function }.


I realize toEqual doesn't do this right now, but how do people get around this when testing objects?  Javascript doesn't have equals/hashcode like the JVM so their is no concept of object equality vs reference equality.  Jasmine it seems compares every key/value pair.  Is there another matcher that automatically excludes function values?

One solution I don't love is to declare the functions outside of the class:

      function isOldEnoughToVote() { return this.age > 18; }
      function Person(name, age) {
        this.name = name;
        this.age = age;
        this.isOldEnoughToVote = isOldEnoughToVote;
      }


In this case, there really is only one function so comparing the same function across multiple instances will result in equality.  Maybe that's better as it is less function creation?  Thoughts?


Davis W. Frank

unread,
Jan 15, 2014, 12:30:55 PM1/15/14
to jasmi...@googlegroups.com
Check out custom equality testers:


That should give you what you need.

--dwf


--
You received this message because you are subscribed to the Google Groups "Jasmine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jasmine-js+...@googlegroups.com.
To post to this group, send email to jasmi...@googlegroups.com.
Visit this group at http://groups.google.com/group/jasmine-js.
For more options, visit https://groups.google.com/groups/opt_out.



--
thx,
--dwf

Matt Hughes

unread,
Jan 15, 2014, 1:16:07 PM1/15/14
to jasmi...@googlegroups.com
I realize I could write custom matchers, but isn't this a pretty common case?  Or am I just doing it wrong by having functions in my models?  

Davis W. Frank

unread,
Jan 15, 2014, 1:30:15 PM1/15/14
to jasmi...@googlegroups.com
It's a fairly common use case, yes. You're not doing it wrong.

We're using code from Underscore.js for equality in Jasmine 2, which solved a lot of issues with our old equality code. Jasmine doesn't want to be in the business of defining equality - Underscore + custom testers seemed like the easiest path for us.

--dwf

Matthias Dailey

unread,
Apr 22, 2014, 2:57:17 PM4/22/14
to jasmi...@googlegroups.com
I found this thread while searching about how to compare object references with Jasmine, instead of just comparing object properties and values.
It seems like (in the Jasmine version I'm using), there is a .toEqual() matcher and a .toBe() matcher. toBe checks if the two variables have a reference to the same object. toEqual looks at the object properties and checks if they and their values match.

changlong Min

unread,
Apr 8, 2016, 5:45:39 PM4/8/16
to Jasmine
I have tried expect().toEqual().
Although, the properties and value are the same, but it threw me error.
Reply all
Reply to author
Forward
0 new messages