More Jasmine Matchers
In my last post I talked about some handy Jasmine matchers. Within hours after publishing that post, I discovered another interesting use for the matchers.
We were attempting to verify some parameters passed with an ajax query. The parameters have a nested structure, and we only cared about some of the parameters at the various levels.
One way to write such a test is to use toEqual
and specify all of
the parameters, even the ones we don’t care about. This
over-constrains the test and makes it brittle in the face of unrelated
changes.
Another way is to deconstruct the parameters and only test the parts of interest:
This works well, but is wordy and makes it hard to see the underlying structure of the expected parameters.
Using jasmine.objectContaining
, we could instead write:
Using jasmine.objectContaining
nested within another object works
just fine here, and allows for a much cleaner test where the expected
output has roughly the same structure as the data it’s matching. It’s
easier to see what’s really expected this way.
jasmine.objectContaining
is one of several
asymmetric matchers,
along with jasmine.any
, jasmine.anything
,
jasmine.arrayContaining
, and jasmine.stringMatching
. You can even
define your own asymmetric matcher by providing an object that has an
asymmetricMatch
function.
When Jasmine compares for equality, it tries very hard to compare them correctly. One of the options is to do an asymmetric comparison if appropriate; another is to recursively check object structure. Thus, it is possible to use any of the asymmetric matchers at any level of an object structure, and Jasmine will just do the right thing.