我正在使用一些代码,其中我需要测试由函数抛出的异常的类型(它是TypeError, ReferenceError等?)
我目前的测试框架是AVA,我可以测试它作为第二个参数t.throws方法,就像这里:
it('should throw Error with message \'UNKNOWN ERROR\' when no params were passed', (t) => {
const error = t.throws(() => {
throwError();
}, TypeError);
t.is(error.message, 'UNKNOWN ERROR');
});
我开始用Jest重写我的测试,但不知道如何轻松地做到这一点。这可能吗?
您必须将期望的函数代码包装在另一个箭头函数中,否则错误将不会被捕获,断言将失败。
要测试的函数:
const testThrowingError = () => {
throw new Error();
};
测试:
describe("error function should Throw Error", () => {
expect(() =>testThrowingError()).toThrowError();
});
资源:
https://jestjs.io/docs/expect#tothrowerror
从我对Jest的接触(尽管有限)中,我发现expect().toThrow()适用于只想测试抛出的特定类型的错误:
expect(() => functionUnderTest()).toThrow(TypeError);
或者抛出一个带有特定消息的错误:
expect(() => functionUnderTest())。toThrow('发生了不好的事情!');
如果你试图同时做这两件事,你会得到一个假阳性。例如,如果你的代码抛出RangeError('坏事发生了!'),这个测试将通过:
expect(() => functionUnderTest()).toThrow(new TypeError('Something bad Happen!'));
bodolsog给出的答案很接近,它建议使用try/catch,但与其期望true为false以确保捕获中的expect断言被命中,不如在测试开始时使用expect.assertions(2),其中2是预期断言的数量。我觉得这更准确地描述了测试的意图。
测试错误类型和消息的完整示例:
describe('functionUnderTest', () => {
it('should throw a specific type of error.', () => {
expect.assertions(2);
try {
functionUnderTest();
} catch (error) {
expect(error).toBeInstanceOf(TypeError);
expect(error).toHaveProperty('message', 'Something bad happened!');
}
});
});
如果functionUnderTest()没有抛出错误,则断言将被命中,但expect.assertions(2)将失败,测试也将失败。