renderHook: Context Provider, state change in child function act() error
まだ誰も着手していません。
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 25/100
- issue の種類
- バグ
- 明瞭さ
- 説明が足りない
- 活発さ
- 停滞
- 技術スタック
- javascript, react
- 領域
- frontend, testing-qa
調査の方向性
useUserSearch フック、その FetchUsers ヘルパー、StoreProvider、および issue に示されているテスト仕様から始めます。モックされた axios レスポンスを使ってフックのテストを実行し、非同期の状態更新を追跡します。issue では、要求される変更も明確な完了条件も定義されていません。
索引モデルが issue の本文から書いたものです。
説明
I have a custom hook that uses a Context Provider for global state management. I am passing a dispatch and data from the state taken from the context inside the hook to a function that will at the end of requesting data from an endpoint dispatch this data coursing a state update inside the context API Provider passed down to the custom hook.
The issue is when I test the custom hook with a wrapper of the Context Provider passed into renderHook() function, I get in the test run the dreaded "act()" error of:
Warning: An update to StoreProvider inside a test was not wrapped in act(...)
20 | .then((res) => {
> 22 | setLoading(false)
| ^
23 | dispatch({
24 | type: ActionTypesEnum.FETCH_USERS,
25 | payload: res.data
you can see the full explanation at: https://stackoverflow.com/questions/76157226/react-hooks-testing-library-context-provider-state-change-in-child-function-ac
The useUserSearch Hook:
const useUserSearch = (searchCriteria: string): SearchHookProps => {
// data from the context and stored in the state
const { dispatch, state } = useStateContext();
const { users } = state;
const [ userData, setUserData ] = useState<UserProps[]>([]);
const [ loading, setLoading ] = useState<boolean>(false);
const [ error, setError ] = useState<boolean>(false);
// connected to the pagination affected by the search
const [ currentPage, setCurrentPage ] = useState<number>(1)
const [ totalPages, setTotalPages ] = useState<number>(1)
const [ totalUserCount, setTotalUserCount ] = useState<number>(0)
const totalPerPage = 12
useEffect(() => {
if (users === null) FetchUsers(dispatch, searchCriteria, setLoading, setError);
}, [users]);
useEffect(() => {
if (searchCriteria.length > 0) FetchUsers(dispatch, searchCriteria, setLoading, setError);
}, [searchCriteria]);
return {
userData,
totalUserCount,
setCurrentPage,
currentPage,
totalPages,
loading,
error,
}
}
FetchUsers function:
const FetchUsers = (
dispatch: Dispatch<any>,
searchCriteria: string,
setLoading: Dispatch<SetStateAction<boolean>>,
setError: Dispatch<SetStateAction<boolean>>,) => {
const { global: { apiUrl } } = AppConfig
const search = `?q=${encodeURIComponent(searchCriteria)}`
setLoading(true)
axios.get(`${apiUrl}/users?q=${search}+in:login+type:user`)
.then((res) => {
setLoading(false)
dispatch({
type: ActionTypesEnum.FETCH_USERS,
payload: res.data
})
})
.catch(() => {
setLoading(false)
setError(true)
})
}
StoreProvider:
import React, { useContext, useReducer, useMemo, createContext } from 'react';
import Reducer from '../../Reducers';
import AppConfig from '../../Configs';
import { StateInterface, StoreInterface, ProviderInterface } from '../../Interfaces';
export const initialState: StateInterface = {
appConfig: AppConfig,
users: null,
};
export const StoreContext = createContext({
state: initialState,
} as StoreInterface);
export const useStateContext = () => useContext(StoreContext);
export const StoreProvider = ({ children }: ProviderInterface) => {
const [state, dispatch] = useReducer(Reducer, initialState);
const StoreProviderValue = useMemo(() => ({ state, dispatch }), [state, dispatch]);
return <StoreContext.Provider value={StoreProviderValue}>{children}</StoreContext.Provider>;
};
The Test spec file:
import React from 'react'
import { render, cleanup, waitFor, renderHook, act } from '@testing-library/react'
import axios from 'axios'
import usersMock from '../__mocks__/usersMock'
import { StoreProvider } from '../Providers'
import useUserSearch from './useUserSearch'
jest.mock('axios')
const mockedAxios = axios as jest.Mocked<typeof axios>;
describe('Test that <User />', () => {
const renderHookComponent = (searchCriteria: string) => {
const wrapper = ({ children }: any) => <StoreProvider>{children}</StoreProvider>
const { result, rerender, unmount } = renderHook(() => useUserSearch(searchCriteria), {
wrapper: wrapper as React.ComponentType<any>
})
return { result, rerender, unmount }
}
afterEach(() => {
cleanup()
})
it('renders the hook useUserSearch', async () => {
mockedAxios.get.mockResolvedValue(usersMock);
const { result } = renderHookComponent('test')
// await waitFor(() => {
// expect(result.current.userData.length).toBe(0)
// })
})
})
- 主要言語
- JavaScript
- スター
- 19.7k
- フォーク
- 1.2k
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
testing-library/react-testing-library のほかの issue
-
fireEvent.select does not wrap its automatic native focus in act対応中かも @sergioperezcheco が 7 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
-
bug: calling configure() without reactStrictMode resets it to undefined, silently disabling strict mode再び着手できるかも @suhailopensource が 77 日前に担当しましたが、オープン中のプルリクエストはありません。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 35/100
testing-library/react-testing-library#1466 · コメント 1 件 ·
-
難易度 4/5 3〜5日 初心者へのやさしさ 30/100
testing-library/react-testing-library#1459 · コメント 2 件 ·
-
perf: optimize container lookup with early exit再び着手できるかも @Ch-Abhinav-Chowdary が 303 日前に担当しましたが、オープン中のプルリクエストはありません。 オープン
難易度 1/5 1時間未満 初心者へのやさしさ 35/100
testing-library/react-testing-library#1430 · コメント 1 件 ·
-
`fireEvent.mouseEnter` does not forward `relatedTarget` (relatedTarget is the window instead)対応中かも @swarnim02 が 321 日前に担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 55/100
testing-library/react-testing-library の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
code-yeongyu/oh-my-openagent#10172 ·
メンテナーはふだん 1 日以内に返信
-
Phase 2 PSA Capability & Career Profile
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
bcgov/digital-journeys#2310 ·
-
難易度 1/5 1時間未満 初心者へのやさしさ 82/100
nodejs/node#66743 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
enhancement good first issue help wanted
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
OWASP/cve-lite-cli#1335 ·
メンテナーはふだん 1 日以内に返信
-
Channels status: needs triage
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
mastra-ai/mastra#27093 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信