概要
Material UI v5(以下MUI v5)を使って開発した独自UIコンポーネントをテストしようと思います。本記事では、UIコンポーネントが仕様通りの色を使って表示されることを検証するユニットテストをJest+React Testing Library(RTL)で作成します。
方法
MUI v5のTheming機能を使うことで、Themeに定義されたpaletteの色でコンポーネントが表示されることをアサートできます。
サンプルコード
import { Button, createTheme, ThemeProvider } from '@mui/material'
// ...
// 以下、テストケース
const colorTheme = createTheme()
render(
<ThemeProvider theme={colorTheme}>
<Button variant="contained" color="secondary">
Secondary Button
</Button>
</ThemeProvider>
)
// Buttonコンポーネントのテキスト色は、variant="contained"ならcontrastTextが使われる
const button = screen.getByRole('button')
expect(button).toHaveStyle(`color: ${colorTheme.palette.secondary.contrastText}`)
解説
MUI v5にはコンポーネントの見た目を定義するThemingという仕組みがあり、MUIコンポーネントは与えられたThemeの見た目で表示されます。代表的な用途として、ライトモード/ダークモードのThemeをアプリ全体に適用するといったものがあります。
さて、MUIコンポーネントの表示色は、基本的にはそのコンポーネント自体とvariant、colorといったpropsで決まります。よって独自UIコンポーネントの表示色に関する仕様は「コンポーネント内のButtonは、variant="contained"
、color="secondary"
で表示する」などと言い換えられます。
上記サンプルコードでは、createTheme()
で作成したデフォルトテーマをThemeProvider
でButton
コンポーネントに適用しています。ここでButtonはMUIコンポーネントですが、これがButtonをラップした独自UIコンポーネントでも同様にThemeが適用されます。React Testing LibraryではDOM要素のスタイルをtoHaveStyle()
マッチャでアサートできるので、ここではbutton要素の文字色に相当するcolor
プロパティが、与えたThemeのpaletteで定義された色と一致するか比較します。
補足1
以下のように、MUIコンポーネントに直接スタイルをベタ書きすると本記事のテスト方法は使えません。他のコンポーネントとの見た目の一貫性が保てなくなるので控えましょう。
<Button sx={{ color: "green" }}>
Secondary Button
</Button>
補足2
このテストケースを書く上で必要なのは対象のDOM要素がTheme.paletteのどの色を使うかですが、これを簡単に知る方法はまだ見つけられていません。もしご存じの方がいらっしゃいましたらご指摘いただけると幸いです。
記事が面白かった方、参考になった方は、是非「イイね」お願いします👍