-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
rejects.toThrow compares only against the message, not the error object #11693
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hey @dankolesnikov! This is not a bug with Jest. There are multiple ways you could access the error object in an async test: For example.. test('should catch 404', async () => {
expect.assertions(1);
await axios('https://google.com/test404').catch((error) => {
expect(error.response.status).toBe(404);
});
}); Or... test('should catch 404 (2)', async () => {
expect.assertions(1);
try {
await axios('https://google.com/test404');
} catch (error) {
expect(error.response.status).toBe(404);
}
}); Note that the But you should also think about what is your responsibility to test. Generally, a good rule is not to write tests that verify the internal workings of external libraries. Because in this case, In the future, I would recommend asking for help on stackoverflow before creating an issue on GitHub. There are many more people who can help there. And it also makes the answer more easily available to others who might have the same or similar questions. ✌️ |
I agree that one can work around this but the jest expect package appears to throw away the thrown error, keeping only the message. This leads to counter-intuitive behavior like the OP's or |
It looks like the prob is that anything that is class Orphan { // `instanceof Error` is false, toEqual compares by properties
constructor(public status: number, public message: string) {}
}
class Child extends Error { // `instanceof Error` is true, toEqual compares only by .message
constructor(public status: number, message: string) {super(message);}
}
const o1a1 = new Orphan(1, "a");
const o1a2 = new Orphan(1, "a"); // o1a2 == o1a1
const o2a = new Orphan(2, "a"); // o2a.status != o1a1.status
const c1a1 = new Child(1, "a");
const c1a2 = new Child(1, "a"); // c1a2 == c1a1
const c2a = new Child(2, "a"); // c2a.status != c1a1.status
test("pass async Orphan equals Orphan", () => {expect(o1a1).toEqual(o1a2);})
test("fail async Orphan equals Orphan", () => {expect(o1a1).toEqual(o2a);})
test("pass async Child equals Child", () => {expect(c1a1).toEqual(c1a2);})
test("fail async Child equals Child", () => {expect(c1a1).toEqual(c2a);}) should pass, fail, pass, fail, but instead the fourth passes. |
Hello, I was facing the same problem. I solved it using the Try the following example: class MyCustomError extends Error {
constructor(public message: string, public customProperty: string) {
super(message)
}
}
test('Custom errors', async () => {
const err = Promise.reject(new MyCustomError('Some Error', 'some value for my property'))
await expect(err).rejects.toMatchObject({ message: 'Some Error', customProperty: 'other value for my property' })
}) It returns: expect(received).rejects.toMatchObject(expected)
- Expected - 2
+ Received + 1
Object {
- "customProperty": "other value for my property",
- "message": "Some Error",
+ "customProperty": "some value for my property",
} |
Nice! I played around with it a bit more and it turns out you need const err = Promise.reject(new MyCustomError('Some Error', 'some value'))
await expect(err).rejects.toMatchObject(new MyCustomError('Some Error', 'other value')) // passes
await expect(err).rejects.toMatchObject({ message: 'Some Error', customProperty: 'other value' }) // fails I recall this being because TS compiles Errors to something odd (at least before ES2015). I remember commenting on an issue or an SO to that effect but can't find it now. [Edit: here's one related TS issue] I expanded my earlier tests (and fixed some labels) using your technique: // Orphans and Children from two comments back
test(" pass Orphan==Orphan", () => {expect(o1a1).toMatchObject(o1a2);})
test(" fail Orphan==Orphan", () => {expect(o1a1).toMatchObject(o2a);})
test(" pass Child ==Child ", () => {expect(c1a1).toMatchObject(c1a2);})
test("!fail Child ==Child ", () => {expect(c1a1).toMatchObject(c2a);})
test(" fail Child ==Child'", () => {expect(c1a1).toMatchObject(Object.assign({}, c2a));})
test(" fail str(Child)==str(Child)", () => {expect(JSON.stringify(c1a1)).toEqual(JSON.stringify(c2a));})
test(" pass async Child==Child ", async () => {await expect(Promise.reject(c1a1)).rejects.toMatchObject(c1a2);})
test("!fail async Child==Child ", async () => {await expect(Promise.reject(c1a1)).rejects.toMatchObject(c2a);})
test(" fail async Child==Child'", async () => {await expect(Promise.reject(c1a1)).rejects.toMatchObject(Object.assign({}, c2a));})
The '!'s flag the non-intuitive lack of failure caused but TSs special treatment of Errors and its subclasses. |
This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 30 days. |
This issue was closed because it has been stalled for 30 days with no activity. Please open a new issue if the issue is still relevant, linking to this one. |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
🐛 Bug Report or Feature Request
Unable to match on the object of the error of the rejected promise.
To Reproduce
Expected behavior
Being able to access the error object and match on its objects.
Essentially I want to do this but without ES Lint yelling at me:
The text was updated successfully, but these errors were encountered: