chai: Deep equality check for Errors
Hi,
because we use chai and chai-as-promised in our project, we recently tried to use .rejectedWith() in order to check for a custom error:
class HttpError extends Error {
constructor(statusCode, message) {
super(message);
this.statusCode = statusCode;
Object.setPrototypeOf(this, new.target.prototype);
this.name = new.target.name;
}
toString() {
return `${this.name}(${this.statusCode}): ${this.message}`;
}
}
But the following check doesn’t work:
it('', async () => {
const httpError = new HttpError(404, 'Not found.');
await expect(Promise.reject(new HttpError(404, 'Not found.'))).to.be.rejectedWith(httpError);
});
This is - as @meeber kindly pointed out here - because of the strict === comparison of the throws() assertion in Chai itself, as chai-as-promised just emulates Chai’s throws().
I personally think that it’d be more useful for errors to have a deep equality check in place. Something like suggested in the linked issue:
.to.deep.throw() => to.be.deep.rejectedWith()
This deep equality check can’t be the same as the normal deep equality check for objects, because of the Error’s stack-trace property, which of course will be not the same in the most cases.
I guess this approach would also not break the existing usage, so it might be a bit simpler than changing the error comparison as a whole.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 16 (8 by maintainers)
Commits related to this issue
- Improve script/category name validation - Use better error messages with more context. - Unify their validation logic and share tests. - Validate also type of the name. - Refactor node (Script/Catego... — committed to undergroundwires/privacy.sexy by undergroundwires 3 years ago
- Improve script/category name validation - Use better error messages with more context. - Unify their validation logic and share tests. - Validate also type of the name. - Refactor node (Script/Catego... — committed to LarrMarburger/privacy.sexy by undergroundwires 3 years ago
I agree with @janis91; I think our deep equality algorithm should special-case
Errorobjects by ignoring the.stackproperty, but consider all other own and inherited enumerable properties.Although the semantics are a bit weird, I also think Chai should support
.deep.throw(errInstance)in order to perform a deep equality comparison against the thrown error, instead of strict equality. Such a change could ride in the wake of #1021.@MicahZoltu part of the plan for Chai 5 is to have matchers, so you could do something like:
The exact syntax and mechanics are not yet hashed out, but it would likely be close to something like this.
Actually the
assertimplementation by node.js actually works —Understood and thank you for sharing this with me. I don’t have a lot of time, but I’m also not saying no, just working on a startup which is taking about 200% of my time 😉 One incentive to help attract maintainers is that github copilot comes free for maintainers of large projects: https://copilot.github.com I’ve been using it 20 days…and I’m def going to continue with it.
@keithamus Will that be able to be used as part of a
.deep.equal(...)? My real problem looks like: