作为任何好的开发人员,您都应始终测试您的代码。
作为任何好的开发人员,您都应始终尝试捕获异常并在编写功能时处理错误。
例如,如果您有这样的函数:
export const logName = name => {
// do something with the name
};
以上功能期望您始终定义一个名称,但不能保证,因此您应该做的是处理名称不确定的情况,并在这种情况下施加例外,并且您的功能应看起来这样:
export const funThatThrows = name => {
if (!name) {
throw new Error('You need the name');
}
// do something with name
};
,如果要测试函数如果未传递的函数给您一个例外的情况,通常您会做的是编写这样的测试:
describe('funThatThrows', () => {
it('should throw an error if name is missing', () => {
expect(() => {
funThatThrows();
}).toThrow();
});
});
本质上,您在传递给expect
的匿名函数中运行函数,然后检查是否会使用toThrow
方法引发异常。
但是,您如何通过返回承诺的功能对其进行测试呢?
现在,如果您的函数不是立即执行,则必须运行某些异步,并仅在解决值时返回该值,也许是这样的:
export const funThatThrowsAsync = async name => {
if (!name) {
throw new Error('You need the name');
}
return Promise.resolve(`hello ${name}`);
};
,如果您尝试将async/await
添加到我们之前所做的测试中,也许是这样:
describe('funThatThrowsAsync', () => {
it('should throw an error if name is missing', () => {
expect(async () => {
await funThatThrowsAsync();
}).toThrow();
});
});
上面的问题是,以上只是在外壳中丢弃错误而不是通过,并使测试失败:
throw new Error('You need the name');
^
Error: You need the name
您需要做的使测试工作的工作是在.toThrow()
之前附加.rejects
方法,从本质上讲具有此公式:
expect(function).rejects.toThrow()
这将告诉Jest您的功能期望丢弃错误,并且会使控制台中的错误保持沉默。
因此,我们的测试应像这样重写:
describe('funThatThrowsAsync', () => {
it('should throw an error if name is missing', () => {
expect(async () => {
await funThatThrowsAsync();
}).rejects.toThrow();
});
});
现在您的测试将通过!
PASS src/async/async.test.js
Test throw with Async/Await
funThatThrows
✓ should throw an error if name is missing (8 ms)
funThatThrowsAsync
✓ should throw an error if name is missing (3 ms)
有关更多信息,您可以查看official documentation。