hooks を使わない React 関数コンポーネントはレンダラーなしで直接呼び、返り値の要素ツリーを検証できる
React
テスト
知識
判断
運用
React の関数コンポーネントは、トップレベルで hooks を呼ばない限りただの純関数なので、jsdom・react-test-renderer・testing-library を追加せずに、テストからコンポーネントを普通の関数として呼び、返り値の React 要素ツリー(type・props・children)をアサートできる。動画合成やチャートなど「実描画には特殊ランタイムが要るがコンポーネント構成は純粋ロジック」という領域で、条件レンダリング・props 配線の退行テストを軽量に書ける。
採用条件と却下基準
- 採用するのは、検証したい対象が「どの子がどの props でツリーに含まれるか」(条件レンダリング、オフセットやフラグの配線、分岐)である場合。リポジトリが「純粋ロジックの単体テストのみ・DOM 環境なし」の方針なら、jsdom や react-test-renderer の依存追加より先にこの方式を検討する。
- 検証対象が描画結果(レイアウト、スタイル適用結果、hooks を含む子の実挙動)なら、この方式では届かないのでレンダラーやビジュアルリグレッションの領域に分ける。
誤解しやすい条件・破綻パターン
- 直接呼べるのは「そのコンポーネント自身が hooks を呼ばない」場合だけ。hooks があると React ランタイム外では invalid hook call で落ちる。子コンポーネントが hooks を使っていても、親の返り値ツリーには要素(type と props)として現れるだけで実行されないため、親の検証は可能。裏返しに、子の内部は一切実行されないので子のロジックはこの方式ではカバーされない。
- children は描画されず要素のまま入っているため、アサートは Children.toArray と isValidElement で要素だけ取り出して type・props を比較する。type は文字列タグまたはコンポーネント参照そのものと比較できる。
- ライブラリ提供のヘルパー関数(アセットパス解決など)が要素生成時に実行される場合、テストランタイム(Node)で throw しないかを先に単体で確かめる。実行時環境チェックだけで文字列を返す実装なら問題なく使える。
テストの空通しを防ぐ観点
条件レンダリングのテストは「全構成 × 全配線値」を明示的にアサートしないと空通しになりやすい。フラグ 2 つなら 4 構成それぞれで、要素数だけでなく各要素の位置指定(オフセット・長さ)とフラグ props を検証する。片側の構成だけ検証すると、フラグの論理積・取り違えのような誤変更(A && B と書くべき所の取り違え、条件付きオフセットの誤配線)が通過する。レビューで「この誤変更を入れたらどのアサーションが落ちるか」を1件ずつ突き合わせると漏れが見つかる。