kar*_*sos 3 redux react-redux react-testing-library redux-toolkit
当尝试测试调度异步 thunk 的组件时,我收到以下警告。它们是由于测试完成后执行的更新而显示的。
console.error
Warning: An update to App inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
at App (/home/karlosos/Dev/nokia/playground/testing-redux/src/App.tsx:6:34)
at Provider (/home/karlosos/Dev/nokia/playground/testing-redux/node_modules/react-redux/lib/components/Provider.js:19:3)
at Wrapper (/home/karlosos/Dev/nokia/playground/testing-redux/src/testUtils.tsx:11:22)
at printWarning (node_modules/react-dom/cjs/react-dom.development.js:86:30)
at error (node_modules/react-dom/cjs/react-dom.development.js:60:7)
at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom.development.js:27589:9)
at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom.development.js:25508:5)
at forceStoreRerender (node_modules/react-dom/cjs/react-dom.development.js:16977:5)
at Object.handleStoreChange [as callback] (node_modules/react-dom/cjs/react-dom.development.js:16953:7)
at node_modules/react-redux/lib/utils/Subscription.js:23:20
Run Code Online (Sandbox Code Playgroud)
修复它们的一种方法是引入某种屏障,该屏障将等待所有挂起的异步操作完成。但是这样做我的测试需要对我不想测试的逻辑进行断言。
我在这里重新创建了一个最小的可重现项目:https ://github.com/karlosos/react-redux-async-warnings/tree/main/src
我的示例测试如下所示:
console.error
Warning: An update to App inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
at App (/home/karlosos/Dev/nokia/playground/testing-redux/src/App.tsx:6:34)
at Provider (/home/karlosos/Dev/nokia/playground/testing-redux/node_modules/react-redux/lib/components/Provider.js:19:3)
at Wrapper (/home/karlosos/Dev/nokia/playground/testing-redux/src/testUtils.tsx:11:22)
at printWarning (node_modules/react-dom/cjs/react-dom.development.js:86:30)
at error (node_modules/react-dom/cjs/react-dom.development.js:60:7)
at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom.development.js:27589:9)
at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom.development.js:25508:5)
at forceStoreRerender (node_modules/react-dom/cjs/react-dom.development.js:16977:5)
at Object.handleStoreChange [as callback] (node_modules/react-dom/cjs/react-dom.development.js:16953:7)
at node_modules/react-redux/lib/utils/Subscription.js:23:20
Run Code Online (Sandbox Code Playgroud)
和例子thunk:
test('WHEN component rendered THEN counter value is being loaded', () => {
// WHEN
renderWithProviders(<App />)
// THEN
expect(Api.getValue).toHaveBeenCalledTimes(1);
const loadingSpinner = screen.getByTestId('loading-spinner');
expect(loadingSpinner).toBeInTheDocument();
// things will happen to the component here after test is done
// precisely the data fetched from API will be displayed
});
Run Code Online (Sandbox Code Playgroud)
waitFor更新 1 -测试结束时使用时没有警告当我await waitFor(() => new Promise(res => setTimeout(res, 0)));在测试结束时添加时,警告不可见。但我不想编辑每个测试用例。这看起来像是一个黑客。
export const fetchCounterValue = (): AppThunk => async (dispatch, getState) => {
if (getState().counter.fetchValueStatus === "loading") {
return;
}
dispatch(fetchValueStart());
try {
const result = await Api.getValue();
dispatch(fetchValueSuccess(result));
} catch (e) {
dispatch(fetchValueError('Could not fetch the data'));
}
};
Run Code Online (Sandbox Code Playgroud)
正确的解决方案不是设置global.IS_REACT_ACT_ENVIRONMENT = false;,而是首先制作正确的测试用例。此act(...) 警告意味着测试完成后组件发生了一些更新。
在这个特定场景中,这是由于加载微调器消失然后显示数据造成的。为了修复这个测试场景,我们需要等待这个加载旋转器消失或者等待数据出现在屏幕上。
\n正确的测试用例应该是这样的:
\n test(\'WHEN component rendered THEN counter value is being loaded\', async () => {\n // WHEN\n renderWithProviders(<App />)\n\n // THEN\n expect(Api.getValue).toHaveBeenCalledTimes(1);\n const loadingSpinner = screen.getByTestId(\'loading-spinner\');\n expect(loadingSpinner).toBeInTheDocument();\n\n await waitForElementToBeRemoved(() => screen.queryByTestId(\'loading-spinner\')); // This is preventing `act(...)` warnings\n });\nRun Code Online (Sandbox Code Playgroud)\n在此处了解有关act(...)警告的更多信息:
| 归档时间: |
|
| 查看次数: |
978 次 |
| 最近记录: |