コードは Jest 環境のものを想定してます。
コンポーネントレンダリング
@testing-library/reactからrenderをインポートしてきて使います。大体はこの関数によりレンダリングしてから色々テストすることになります。
import {render} from '@testing-library/react';
const Button = ({children}) => (
);
test('...', () => {
const renderResult = render();
// ...
});renderはRenderResultを返しますが、これは色々なものが詰まったオブジェクトです。
debug
debugはどんな DOM 構造でレンダリングされたか確認したい時に便利なものです。
renderResult.debug();
//
//
//
//
// 引数としてbaseElementが渡せます。これを渡すと表示する DOM の範囲を狭めれます。
renderResult.debug(renderResult.container);
//
//
// container
レンダリングする要素の入れ物となるコンポーネントです。デフォルトでは<div>で囲まれます。(つまり、div > button > spanの構造でレンダリングされる)
入れ物はrender時にオプションを指定することで変更可能です。
const article = document.createElement("article");
render(, {
container: document.body.appendChild(article)
}).debug();
//
//
// Queries
要素を取得するための様々なヘルパーです。get.*、find.*、query.*から始まるメソッドが多数用意されてます。これらの違いはgetとfindは必ず要素が無ければ駄目で、queryは無くても良い点大きく違う点です。
また、Allと付くヘルパー(例えばgetAllBy.*)は単体ではなく配列で返すようになります。
Queries はByまたはAllByの後ろに決められたサフィックス(手段名)を付けることで、その手段で要素を取得します。検索文字は絶対マッチでも良いですが、/foo/iのような正規表現でもマッチさせれます。
手段には以下のようなものがあります。LabelTextは以下のようなケースの<label>を取得します。
label > inputlabel[aria-label]label[for] + input[id]label[id] + input[aria-labelledby]
PlaceholderTextはplaceholder属性を持つ要素を取得します。
[placeholder]
Textはそのテキストを持ってる要素を取得します。
{text}
AltTextはalt属性を持つ要素を取得します。
[alt]
Titleはtitle属性を持つ要素か SVG のタイトルとマッチした要素を取得します。
[title]svg > title
DisplayValueは入力系の要素に現在入ってる値にマッチした要素を取得します。
inputtextareaselect > option[selected]
Roleは要素の役割にマッチした要素を取得します。これは HTML によってデフォルトで割り振られた Role にもマッチします。
デフォルトロールはmomdo.github.io/html-aria/#document-conformance-requirements-for-use-of-aria-attributes-in-htmlが参考になります。
[role]
TestIdはdata-testid属性を持つ要素を取得します。
[data-testid]
rerender
rerenderはそのコンポーネントを再レンダリングできます。これは(下記の)fireEventなどでコンポーネント内部の状態が変わった時にそれを反映させれます。
以下はレンダリング後はテキスト要素があるが、再レンダリング後は無くなっている事をテストしている例です。
import React from 'react';
import {render, fireEvent} from '@testing-library/react';
const Button = ({children}) => {
const [hide, setHide] = React.useState(false);
return (
);
};
test('hide text when has clicked', () => {
const renderResult = render();
const button = renderResult.getByRole('button');
expect(renderResult.getByText('foo')).toBeTruthy();
fireEvent.click(button);
renderResult.rerender();
expect(() => renderResult.getByText('foo')).toThrow();
});unmount
unmountはコンポーネントを JSDOM 環境から取り除きます。例えばコンポーネントが内部で外部の DOM を弄っている場合、その後処理がちゃんとできているかなどの確認に使えます。
イベント発火
fireEventでは Queries などから取得した要素を引数にイベントを Dispatch できます。
import {fireEvent} from '@testing-library/react';
// ...
fireEvent.click(getByRoke('button'));