NISHIO Hirokazu[Translate]
useStateを差し替える
useStateを差し替える

コンポーネントの中でsetValueしている場合に、これがactで包まれていないと警告される

output
console.error Warning: An update to MyAsyncComponent inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): ... 15 | console.log(6); > 16 | setValue(x); | ^

簡単な解決策としては「何もしないact実装を用意して本体コード中でそれを使っておき、テストの時だけ本物に差し替える」という案もあるが、なんとなく嫌なので useStateを差し替える。

MockUseState.ts
import React, { Dispatch, useCallback } from "react"; import { act } from "@testing-library/react"; import { useState as originalUseState } from "react"; export const mockUseState = () => { return jest.spyOn(React, "useState").mockImplementation((arg?: unknown): [ unknown, Dispatch<unknown> ] => { const [s, dispatch] = originalUseState(arg); const wrappedDispatch = useCallback( (arg: unknown): void => { act(() => { dispatch(arg); }); }, [dispatch] ); return [s, wrappedDispatch]; }); };
updated 2021-03-12

test.tsx
let m_mockUseState: jest.SpyInstance<[unknown, React.Dispatch<unknown>], []>; beforeEach(() => { m_mockUseState = mockUseState(); }); afterEach(() => { m_mockUseState.mockRestore(); });

"Engineer's way of creating knowledge" the English version of my book is now available on [Engineer's way of creating knowledge]

(C)NISHIO Hirokazu / Converted from [Scrapbox] at [Edit]