测试触发async thunk的React组件时出现act警告的解决方案咨询
React组件测试中Dispatch异步Thunk的act警告问题
警告信息
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
问题场景
测试包含异步Thunk的React组件时,测试结束后组件仍会执行状态更新,触发上述act(...)警告。已知等待所有异步动作完成可以解决,但这会让测试混入无需验证的逻辑;也试过在测试末尾添加临时hack代码消除警告,但不想逐个修改所有测试用例,寻求更优的批量/全局解决方案。
示例代码
测试用例
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(); // 测试结束后组件仍会执行后续操作 // 具体是API返回数据后更新组件显示 });
异步Thunk
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')); } };
已尝试的临时方案
在测试末尾添加以下代码可以消除警告,但属于临时hack:
await waitFor(() => new Promise(res => setTimeout(res, 0)));
内容的提问来源于stack exchange,提问作者karlosos
相关产品推荐
相关产品推荐

