我正在使用一些代码,其中我需要测试由函数抛出的异常的类型(它是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重写我的测试,但不知道如何轻松地做到这一点。这可能吗?
我最终为我们的test-utils库编写了一个方便的方法
/**
* Utility method to test for a specific error class and message in Jest
* @param {fn, expectedErrorClass, expectedErrorMessage }
* @example failTest({
fn: () => {
return new MyObject({
param: 'stuff'
})
},
expectedErrorClass: MyError,
expectedErrorMessage: 'stuff not yet implemented'
})
*/
failTest: ({ fn, expectedErrorClass, expectedErrorMessage }) => {
try {
fn()
expect(true).toBeFalsy()
} catch (err) {
let isExpectedErr = err instanceof expectedErrorClass
expect(isExpectedErr).toBeTruthy()
expect(err.message).toBe(expectedErrorMessage)
}
}
这有点奇怪,但它是有效的,以我之见是很好的可读性:
it('should throw Error with message \'UNKNOWN ERROR\' when no parameters were passed', () => {
try {
throwError();
// Fail test if above expression doesn't throw anything.
expect(true).toBe(false);
} catch (e) {
expect(e.message).toBe("UNKNOWN ERROR");
}
});
Catch块捕获您的异常,然后您可以测试您引发的Error。奇怪的期待(真正的).toBe(假);如果没有抛出预期的错误,则需要测试失败。否则,这一行永远无法到达(Error应该在它们之前引发)。
@Kenny Body提出了一个更好的解决方案,如果你使用expect.assertions(),可以提高代码质量:
it('should throw Error with message \'UNKNOWN ERROR\' when no parameters were passed', () => {
expect.assertions(1);
try {
throwError();
} catch (e) {
expect(e.message).toBe("UNKNOWN ERROR");
}
});
请参阅原始答案和更多解释:如何在Jest中测试抛出异常的类型
2022年编辑:
要使用这种方法而不触发no-conditional-expect规则(如果你使用eslint-plugin-jest),该规则的文档建议使用错误包装器:
class NoErrorThrownError extends Error {}
const getError = async <TError>(call: () => unknown): Promise<TError> => {
try {
await call();
throw new NoErrorThrownError();
} catch (error: unknown) {
return error as TError;
}
};
describe('when the http request fails', () => {
it('includes the status code in the error', async () => {
const error = await getError(async () => makeRequest(url));
// check that the returned error wasn't that no error was thrown
expect(error).not.toBeInstanceOf(NoErrorThrownError);
expect(error).toHaveProperty('statusCode', 404);
});
});
参见:no-conditional-expect文档