Using jasmine.contains() to check that objects contain certain key/value pairs

12,406 views
Skip to first unread message

Noah Easterly

unread,
Mar 7, 2012, 4:33:21 PM3/7/12
to Jasmine
I've got some methods that are passing around big honking objects
(BHOs), and since specific codepaths only affect parts of the BHO,
it's a bit of a pain in the tuckus to specify the entire BHO every
time I want to do a `expect( ... ).toEqual( ... )` or a
`expect( ... ).toHaveBeenCalledWith( ... )`. It's line-noise in my
tests, and means I have to change unrelated tests when some
functionality changes.

So, with that in mind, I stuck `jasmine.contains()` in my
`SpecHelpers.js` file, and I'd thought I'd post it here if it might be
useful to other folks (or if you all wanted to school me on my code).

`jasmine.contains()` lets you be a bit more fine grained than
`jasmine.any(Object)` without having to specify all the pairs in the
object.

jasmine.contains = function(expectedPairs){
return new jasmine.Matchers.Contains(expectedPairs);
};
jasmine.Matchers.Contains = function(expectedPairs){
this.expectedPairs = expectedPairs;
this.env = jasmine.getEnv();
};
// subclass jasmine.Matchers.Any so that env.equals_ calls our
custom matches method
jasmine.Matchers.Contains.prototype = jasmine.any(Object);
jasmine.Matchers.Contains.prototype.toString = function(){
return '<jasmine.contains(' + jasmine.pp( this.expectedPairs ) +
')>';
};
jasmine.Matchers.Contains.prototype.classMatches =
jasmine.Matchers.Contains.prototype.matches;
jasmine.Matchers.Contains.prototype.matches = function(other){
if (!this.classMatches(other))
return false;

for (var property in this.expectedPairs)
if (!this.env.equals_(this.expectedPairs[property],
other[property])
return false;

return true;
};


So that's not a lot of code, but it's pretty handy:

expect( foo.bar ).toHaveBeenCalledWith( 'baz',
jasmine.contains({ quux: jasmine.Any(Number) }) );

If there's interest, I could always send it as a pull request to the
github project and see what the devs think.

Noah Easterly

unread,
Mar 7, 2012, 4:41:31 PM3/7/12
to Jasmine
Or you can just ignore me, since I'm apparently using an old version of Jasmine that doesn't have jasmine.objectContaining() yet.

My bad :)

Jasmine Hegman

unread,
Apr 25, 2013, 1:09:58 PM4/25/13
to jasmi...@googlegroups.com
This is very old, found it randomly, but I wanted to provide an alternate that may or may not be handy in its own ways over jasmine.objectContaining(...):

With objectContaining:
            expect( someFuncSpy ).toHaveBeenCalledWith( jasmine.objectContaining({ minLength: 2 }));

Alternate method:
            expect( someFuncSpy.mostRecentCall.args[0].minLength ).toBeDefined();
            expect( someFuncSpy.mostRecentCall.args[0].minLength ).toEqual(2);

Not sure of what specific benefit one might gain by doing this manually but I hope this helps someone if they happen to need another specific matcher on one of those object's keys for some reason...
Reply all
Reply to author
Forward
0 new messages