はじめに
先日、業務においてReactのバージョンをv17からv18にアップグレードしました。
このアップグレードに伴い、使用していた@testing-library/react-hooksライブラリも@testing-library/reactに移植する必要が生じました。
@testing-library/react-hooksは、React v17以前のバージョンでコンポーネントをテストするためのライブラリでしたが、React v18では新しいRoot APIが導入されたことで、@testing-library/react-hooksは非推奨となり、@testing-library/reactに統合されました。
今回は、業務において@testing-library/react-hooksを@testing-library/reactに移植した時やったことについて解説します。
扱うテスト関数
今回はuseSetTimeoutというカスタムフックのテストを例に説明していきます。
useSetTimeoutはReactのsetTimeout
とclearTimeout
を抽象化したカスタムフックで、タイムアウトの設定とキャンセルを簡単に扱えるようにしています。返り値は[SetTimeout, ClearTimeout, boolean]型です。
RenderResult→RenderHookResult
@testing-library/react-hooksのrenderHook
関数は、RenderResult
型を返していましたが、@testing-library/reactではRenderHookResult
型に変更されました。この変更に対応するため、以下のようにコードを修正しました。setTimeoutのテストの一部分のみを抽出しております。
import type { RenderResult } from '@testing-library/react-hooks';
import { renderHook } from '@testing-library/react-hooks';
import useSetTimeout from './useSetTimeout';
class CurrentResult {
constructor(
private renderResult: RenderResult<ReturnType<typeof useSetTimeout>>
) {}
get setTimeout() {
return this.renderResult.current[0];
}
}
describe('useSetTimeout', () => {
let currentResult: CurrentResult;
beforeEach(() => {
const { result } = renderHook(() => useSetTimeout());
currentResult = new CurrentResult(result);
});
import type { RenderHookResult } from '@testing-library/react';
import { renderHook } from '@testing-library/react';
import useSetTimeout from './useSetTimeout';
class CurrentResult {
constructor(
private renderResult: RenderHookResult<
ReturnType<typeof useSetTimeout>,
unknown
>
) {}
get setTimeout() {
return this.renderResult.result.current[0];
}
}
describe('useSetTimeout', () => {
let currentResult: CurrentResult;
beforeEach(() => {
const renderHookResult = renderHook(() => useSetTimeout());
currentResult = new CurrentResult(renderHookResult);
});
終わりに
@testing-library/react-hooksから@testing-library/reactへの移植は、React v18へのアップグレードの際には必須となる作業です。
本記事では、その際に業務においてやったことをuseSetTimeoutフックを例に解説しました。
内容としては型定義を見ればすぐに行えるものですが、少々苦戦したので備忘録として残したいと思いました。