I have this custom error defined (file name: 'errors.ts'):
export class CustomError extends Error {
constructor(message?: string) {
super(message);
Object.setPrototypeOf(this, Error.prototype);
this.name = this.constructor.name;
}
}
And I have this module using that error (file name: 'main.ts'):
import { CustomError } from './errors';
let called = false;
export default {
throwAfterFirst: (): void => {
if (called) throw new CustomError();
called = true;
},
};
I want to check with jest using dynamic imports so I could call jest.restModule() to reset called variable. This is the test file:
import { CustomError } from './errors';
let main: typeof import('./main').default;
const load = async (): Promise<Main> => {
jest.resetModules();
main = (await import('./main')).default;
};
describe('Main', () => {
beforeEach(async () => {
await load();
});
it('should throw on second time', () => {
manager.throwAfterFirst();
expect(() => manager.throwAfterFirst()).toThrowError(CustomError);
});
it('should still throw on second time', () => {
manager.throwAfterFirst();
expect(() => manager.throwAfterFirst()).toThrowError(CustomError);
});
});
Now this is half working since the module is indeed reset before each test but the problem is toThrowError isn't matched correctly and I get the following error for both tests on the second line:
expect(received).toThrowError(expected)
Expected constructor: CustomError
Received constructor: CustomError
.
.
.
This weird bug does not occur with regular errors (e.g. replace CustomError with TypeError).
Also, CustomError can be matched successfully without dynamic importing.
For example, the following test works fine:
import { CustomError } from './errors';
import main from './main';
describe('Main', () => {
it('should throw on second time', () => {
manager.throwAfterFirst();
expect(() => manager.throwAfterFirst()).toThrowError(CustomError);
});
});
Since I'm using dynamic import CustomError is not recognized correctly (perhaps not the same prototype?). What am I missing here, and how can I fix the test?
(I still want to check specific error and not use toThrow which match any error. BTW toThrow works on this scenario).