React Hooks のテストを react-hooks-testing-library で書く
React Hooksのテストには react-testing-library
を使っていたのですが、 react-hooks-testing-library
を試したところ、なかなか良かったので簡単に紹介します。
react-hooks-testing-library
とは
GitHub はこちら: https://github.com/testing-library/react-hooks-testing-library
Hooksをテストする際に、コンポーネントのコンテキスト内で実行するのでなく、 Hooksを直接呼び出してテストできるライブラリです。
もともとは react-testing-library
と完全に別のパッケージだったようですが、
react-testing-library
でも似たような機能を開発中であったことreact-hooks-testing-library
の作者がreact-testing-library
を意識して作成していたこと
から、最近 testing-library
ファミリーに移動したようです。
useStateのテスト
たとえばこのような useState
を使った Hooks をテストするとします。
単純に、Menuの開閉を状態に持ち、toggleする関数を作っただけです。
import { useState } from 'react'; export const useMenuOpen = () => { const [isOpen, setIsOpen] = useState(false); const toggle = () => setIsOpen(!isOpen); return { isOpen, setIsOpen, toggle }; };
これのテストは、下のように書けます。
ここで react-hooks-testing-library
から import している act()
は、'react-test-renderer'が提供しているものと同じものです。
import { act, renderHook } from '@testing-library/react-hooks'; import { useMenuOpen } from './useMenuOpen'; it('should toggle', () => { const { result } = renderHook(() => useMenuOpen()); // 初期状態 expect(result.current.isOpen).toBe(false); // 開閉する act(() => { result.current.toggle(); }); expect(result.current.isOpen).toBe(true); // もう一度開閉する act(() => { result.current.toggle(); }); expect(result.current.isOpen).toBe(false); });
react-testing-library
を使うときように、何らかのコンポーネントをレンダリングする必要はありません。
純粋にHooksだけのテストを書くことができます。
つかいどころ
react-hooks-testing-library
を使えば、
適当なコンポーネントを記載する必要がないので、
Hooksのロジックのテストだけに集中できます。
しかし、Hooksのテストをすべて置き換えるものではなく、状況に応じて使い分けるべきです。
react-testing-library
の README では、このように書いてあります。
NOTE it is not recommended to test single-use custom hooks in isolation from the components where it's being used. It's better to test the component that's using the hook rather than the hook itself. The React Hooks Testing Library is intended to be used for reusable hooks/libraries.
つまり、特定のコンポーネントに紐付いたHooksなどは、これまで同様に react-test-library
を使ってコンポーネントそのものをテストと良いでしょう。クリック時のHooksの挙動などをテストする場合ですね。
一方、特定のコンポーネントに結びついていないHooks、例えば汎用的に使うHooksやパッケージ用に書いているHooksなどは、こちらの react-hooks-testing-library
を使うほうがテストが見通しよく書けると思います。
以上です。
とりあえずしばらく使ってみようと思います。