【发布时间】:2021-06-03 15:27:05
【问题描述】:
我想测试以下代码。
const Component: React.FC = () => {
const handleSubmit = (action) => {
doSomethingAsynchronous()
.then(() => /* something on success */)
.catch((err) => {
// Display the error message
action();
// Rethrow the exception so it can be handled up the chain
throw err;
})
}
return <Form onSubmit={handleSubmit} />;
}
此代码执行一个失败或解决的简单异步操作。失败时,组件会重新渲染以显示错误消息,并重新抛出错误以记录到控制台/我们的日志系统并供父组件处理。
当我尝试测试错误处理行为以确保设置了错误消息时,问题就出现了。简单的测试如:
describe('Component', () => {
it('handles an error', async () => {
// Setup
const mockAction = jest.fn();
const render = shallowRender(<Component />);
submissionHandler = render.find(Component).invoke('onSubmit');
// Act
submissionHandler(mockAction);
await () => new Promise(setImmediate); // To wait for promise execution
// Assert
expect(mockAction).toHaveBeenCalled();
})
})
导致 Jest 测试失败,因为组件在测试块中的 catch 块内抛出了错误(如预期的那样)。但是,我试图抑制这种情况也会导致抛出相同的错误并导致测试失败。
try {
// Act
submissionHandler(mockAction);
await () => new Promise(setImmediate); // To wait for promise execution
} catch (e) {}
我也尝试过使用expects().toThrow(),但这反而会返回开玩笑的错误Received function did not throw。我认为这是因为由于承诺执行不再在同一个函数范围内,所以 Jest 不会将其识别为源自该函数吗?
await expect(async () => {
submissionHandler(mockAction);
await () => new Promise(setImmediate);
}).toThrow();
有人知道最好的测试方法吗?我知道我可以通过让onSubmit 在此处返回我的承诺并在此处捕获异常来作弊,但我会避免这样做以阻止我的函数返回以进行测试。
【问题讨论】:
-
它不会抛出;这是一个承诺,它拒绝
await expect(...).rejects...。但是在您的情况下,在handleSubmit之外无法访问承诺链,因此没有“链上”来处理它 - 这只是一个未处理的承诺拒绝。
标签: javascript reactjs testing jestjs es6-promise