React18 にて testing-library/react のrenderHook の wrapper へ Props を更新してテストがしたいんじゃ
React18になり、今まで使っていた testing-library/react-hooks が使えなくなったことはもう周知の事実。しかし、renderHook に wrapper を渡してprops を変更してテストしていた項目を testing-library/react の renderHook で代用するのがむずかったのでここに残す。
/**
* hook関数を実行し、返された値を検証するための必要な環境を提供するReactコンポーネントを定義し、
* それをラップして renderHook関数を呼び出します
*
* @param hook // テスト対象のReact Hooksの関数
* @param provider // hook 関数で使用されるReactコンポーネントのプロバイダーとして使用されるコンポーネント
* @param options // テストのオプション、およびラッパーコンポーネントのプロパティ
*
* NOTICE: テストコードで使用するので @ts-ignore を許容しています。使わない方法があったらそちらを使っていきたいところ
*/
export const customRenderHook = <
Props,
Q extends Queries,
Container extends Element | DocumentFragment,
BaseElement extends Element | DocumentFragment,
Result,
>(
hook: (props?: Props) => Result,
provider: React.ComponentType<Props>,
options?: Omit<RenderHookOptions<Props, Q, Container, BaseElement>, 'wrapper'> & {
wrapperProps?: Props & { value: IStoreContext };
},
): RenderHookResult<Result, Props> => {
// props引数から wrapperProps を分離し、 provider引数を使用して子要素を含めたReactコンポーネントを生成
const Wrapper: React.FC<Props & { children: React.ReactNode }> = ({ children, ...rest }) => {
const WrapperComponent = provider as React.ComponentType<Omit<Props, 'children'>>;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return <WrapperComponent {...rest}>{children}</WrapperComponent>;
};
// wrapperプロパティを含む renderHook関数を返す
return renderHook(hook, {
...options,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
wrapper: props => <Wrapper {...options?.wrapperProps} {...props} />,
});
};
この記事が気に入ったらサポートをしてみませんか?