asserting against thrown error objects in jest
You need to throw a Javascript Error
object, so the Jest toThrowError
method identifies that an error has been thrown. Also the toThrowError
looks to match the message of the error thrown or if an error has been thrown if you just check by .toThrowError()
.
it('should throw', () => {
const errorObj = {
myError: {
name: 'myError',
desc: 'myDescription'
}
};
const fn = () => {
throw new Error(errorObj.myError.desc);
}
expect(() => fn()).toThrowError("myDescription");
});
If you want to check the whole object is being passed as it is, you need to check it like this:
it('should throw', () => {
const errorObj = {
myError: {
name: 'myError',
desc: 'myDescription'
}
};
const fn = () => {
throw errorObj;
}
expect(() => fn()).toThrowError(new Error(errorObj));
});
If you are looking to test the contents of a custom error (which I think is what you are trying to do). You could catch the error then perform an assertion afterwards.
it('should throw', () => {
let thrownError;
try {
fn();
}
catch(error) {
thrownError = error;
}
expect(thrownError).toEqual(expectedErrorObj);
});
As Dez has suggested the toThrowError function will not work if you do not throw an instance of a javascript Error object. However, you could create your custom error by decorating an instance of an error object.
e.g.
let myError = new Error('some message');
myError.data = { name: 'myError',
desc: 'myDescription' };
throw myError;
Then once you had caught the error in your test you could test the custom contents of the error.
expect(thrownError.data).toEqual({ name: 'myError',
desc: 'myDescription' });
It's known issue in jest, see https://github.com/facebook/jest/issues/8140
Meanwhile, here is my workaround - https://github.com/DanielHreben/jest-matcher-specific-error
If the objective is to check partial content of error, we can use Jest expect.objectContaining to help us keep code simple and check object payload returned as error :
const invalidJob = () => {
throw {
type: '/errors/invalid-job',
message: 'This job is invalid',
};
};
expect(() => invalidJob()).toThrowError(
expect.objectContaining({
type: '/errors/invalid-job',
})
);
Also possible with nested objects :
const invalidJob = () => {
throw {
response: {
type: '/errors/invalid-job',
message: 'This job is invalid',
},
status: 400
};
};
expect(() => invalidJob()).toThrowError(
expect.objectContaining({
status: 400,
response: expect.objectContaining({
type: '/errors/invalid-job'
})
})
);