We've developed a rather big set of custom jasmine matchers that helps to make our code cleaner and avoid code duplication. I've noticed that some of the custom jasmine matchers use ===
equality testing and some jasmine.matchersUtil.equals
. Example:
toHaveHandCursor: function() {
return {
compare: function(actual) {
return {
pass: actual.getCssValue("cursor").then(function(cursor) {
return cursor === "pointer";
})
};
}
};
},
toBeActive: function() {
return {
compare: function(elm) {
return {
pass: protractor.promise.all([
elm.getId(),
browser.driver.switchTo().activeElement().getId()
]).then(helpers.spread(function (currentElementID, activeElementID) {
return jasmine.matchersUtil.equals(currentElementID, activeElementID);
})),
message: "Element is not active."
};
}
};
}
The Question:
What is the difference between jasmine.matchersUtil.equals
and ===
equality testing and which method should be preferred?
In other words, in general, do we risk if we are using ===
only?
As far as i understand, here are few things that i found for jasmine.matchersUtil.equals
and ===
:
By definition, ===
compares the two entities based on its value
and type
. Its a strict
comparison operator. For ex:
2 === 2 //true
2 === 3 //false
2 === '2' //false
0 === -0 //true
(Sample scenario where +0, 0 and -0 can appear)
On the other hand, jasmine.matchersUtil.equals
is implemented based on the _.isEqual
logic of underscorejs and tests for equality based on a logic that determines if the entities passed to it should be considered equal even if their types
are different. Something like this -
jasmine.matchersUtil.equals(2, 2) //true
jasmine.matchersUtil.equals(2, 3) //false
jasmine.matchersUtil.equals(2, '2') //false
jasmine.matchersUtil.equals(0, -0) //false
Here's an extract of it from the git repo -
// Identical objects are equal. `0 === -0`, but they aren't identical.
if (a === b) { return a !== 0 || 1 / a == 1 / b; }
EDIT:
Added advantage of jasmine.matchersUtil.equals()
is that we can actually implement our own custom equality testers so that few scenarios which are thought to create issues can be avoided. Here's a sample of a custom equality tester that's used with below examples -
var customTester = function(first, second) {
return first == second;
};
Few scenarios -
Suppose if there is a need to check if an element text is empty or has some specific value and there is a custom jasmine matcher developed for it, then -
"5" === 5 //if operation on elem returns "5" then custom matcher gives false
jasmine.matchersUtil.equals("5", 5, customTester) //true when implemented with custom equality testers
undefined === null //if operation on elem returns undefined then custom matcher gives false
jasmine.matchersUtil.equals("", null, customTester) //true when implemented with custom equality testers
NaN === NaN //if operation on elem returns NaN then custom matcher gives false
jasmine.matchersUtil.equals(NaN, NaN) //true
Checking the equality of objects is easier using custom matchers. For ex:
{name: 'hill'} === {name: 'hill'} //false
jasmine.matchersUtil.equals({name: 'hill'}, {name: 'hill'}) //true
Check for equality of element's return value with regular expressions is easier using custom matchers rather than implementing the logic using ===
.
Comparison of constructors is easier.
Verification of errors is handled if an error occurrence needs to be tested by passing the error object to the custom matcher.
We always used custom matchers whenever we knew that there can be different values other than the expected one's that can arise, or any of the above conditions can occur. If the expectation is guaranteed to be a single value then using ===
makes sense. Hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With