コードは 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 > input
label[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
は入力系の要素に現在入ってる値にマッチした要素を取得します。
input
textarea
select > 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'));