Deep equality check for Errors
See original GitHub issueHi,
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.
Issue Analytics
- State:
- Created 6 years ago
- Comments:16 (8 by maintainers)
Top GitHub Comments
I agree with @janis91; I think our deep equality algorithm should special-case
Error
objects by ignoring the.stack
property, 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.