我定义了此自定义错误(文件名:'errors.ts'):
export class CustomError extends Error {
constructor(message?: string) {
super(message);
Object.setPrototypeOf(this, Error.prototype);
this.name = this.constructor.name;
}
}
我有这个模块使用该错误(文件名:'main.ts'):
import { CustomError } from './errors';
let called = false;
export default {
throwAfterFirst: (): void => {
if (called) throw new CustomError();
called = true;
},
};
我想通过动态导入来开玩笑地检查,因此我可以调用jest.restModule()
来重置called
变量。这是测试文件:
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);
});
});
现在这工作了一半,因为确实在每次测试之前都会重置模块,但是问题是toThrowError
不能正确匹配,第二行的两个测试都出现以下错误:
expect(received).toThrowError(expected)
Expected constructor: CustomError
Received constructor: CustomError
.
.
.
这个奇怪的错误不会因常规错误而发生(例如,将CustomError
替换为TypeError
)。
另外,CustomError
可以成功匹配而无需动态导入。
例如,以下测试可以正常工作:
import { CustomError } from './errors';
import main from './main';
describe('Main', () => {
it('should throw on second time', () => {
manager.throwAfterFirst();
expect(() => manager.throwAfterFirst()).toThrowError(CustomError);
});
});
由于我使用的是动态导入CustomError
,因此无法正确识别(也许不是同一原型?)。我在这里缺少什么,如何修复测试?
(我仍然想检查特定的错误,不使用与任何错误匹配的toThrow
。顺便说一句,toThrow
适用于这种情况)。
答案 0 :(得分:0)
我发现的解决方法是:
let main: typeof import('./main').default;
let Errors: typeof import('./errors');
const load = async (): Promise<void> => {
jest.resetModules();
main = (await import('./main')).default;
Errors = await import('./errors');
};
describe('Main', () => {
beforeEach(async () => {
await load();
});
it('should throw on second time', () => {
manager.throwAfterFirst();
expect(() => manager.throwAfterFirst()).toThrowError(Errors.CustomError);
});
it('should still throw on second time', () => {
manager.throwAfterFirst();
expect(() => manager.throwAfterFirst()).toThrowError(Errors.CustomError);
});
});