スタイルテスト
jest-styled-components
モジュールを使うことで「このコンポーネントはcolor
をorange
で持ってるはず」をテストできます。
使うにはスナップショットの時などと同じくjest-styled-components
をただインポートすれば、toHaveStyleRule
というマッチャーが使えるようになります。
ここでは@testing-library/react
と共に使い方を見ていきます。
使い方
toHaveStyleRules
は styled-components のルートとなる要素に対して使用するマッチャーです。
基本
@testing-library/react
を使っているので軽く説明すると、以下のコードは`、
queryByRole
によって<button>
要素を取得- その要素に対してマッチャー使用
をしています。
import React from "react";
import styled from "styled-components";
import { render } from "@testing-library/react";
import "jest-styled-components";
const Button = styled.button`
color: orange;
`;
test("the color of the component is orange", () => {
const renderResult = render(<Button />);
expect(
renderResult.queryByRole("button")
).toHaveStyleRule("color", "orange");
});
<button>
要素に対しての#toHaveStyleRule("color", "orange")
によって、この要素がcolor: orange
というスタイルを持っている事がテストできます。そしてこのテストはパスします。
またもし、色の具体地は重要ではなくcolor
を持っていることが重要というような場合、Jest のexpect
オブジェクトのexpect.any
などは使えます。 例えば、以下のようにcolor
に何かしらの色値が入ってることをテストできます。
expect(renderResult.queryByRole("button")).toHaveStyleRule(
"color",
expect.any(String)
);
スコープ使用なコンポーネントでテスト
スコープを使用して1つのstyled-components
で複数の要素に対してスタイル付けする事があります。上記のコードをスコープ使用な形に書き換えました。
こちらはスタイルをbutton { }
というネスト構造で書いてます。
import React from "react";
import styled from "styled-components";
import { render } from "@testing-library/react";
import "jest-styled-components";
const Button = styled(({ className }) => {
return <button className={className} />;
})`
button {
color: orange;
}
`;
test("the color of the component is orange", () => {
const renderResult = render(<Button />);
expect(
renderResult.queryByRole("button")
).toHaveStyleRule("color", "orange", {
modifier: "button"
});
});
この場合は3つ目の引数にmodifier
を持ったオブジェクトを渡します。ここへセレクタを渡すことで、深いネストのセレクタの要素のスタイルでも問題なくテストできます。
メディアクエリ持ちのテスト
レスポンシブなスタイルにも対応してます。下記はスマホではcolor: blue
、PC ではcolor: orange
であることをテストしてます。
import React from "react";
import styled from "styled-components";
import { render } from "@testing-library/react";
import "jest-styled-components";
const Button = styled(({ className }) => {
return <button className={className} />;
})`
@media (max-width: 767px) {
button {
color: blue;
}
}
@media (min-width: 768px) {
button {
color: orange;
}
}
`;
test("the color of the component is orange", () => {
const renderResult = render(<Button />);
const button = renderResult.queryByRole("button");
expect(button).toHaveStyleRule("color", "blue", {
media: "(max-width: 767px)",
modifier: "button"
});
expect(button).toHaveStyleRule("color", "orange", {
media: "(min-width: 768px)",
modifier: "button"
});
});
3つ目の引数のオブジェクトにmedia
というプロパティを増やし、値を確認したいメディアクエリと同じ値にするだけです。
複雑なコンポーネントでテスト
ここでいう複雑なというのは、ネストしたセレクタにstyled-components
を使ってるようなケースを指してます。例えば、
const Span = styled.span``;
const Button = styled.button`
${Span} {
color: orange;
}
`;
のようなケースです。全体像は以下です。
import React from "react";
import styled, { css } from "styled-components";
import { render } from "@testing-library/react";
import "jest-styled-components";
const Span = styled.span``;
const Button = styled(({ className }) => {
return (
<button className={className}>
<Span />
</button>
);
})`
${Span} {
color: orange;
}
`;
test("the color of the component is orange", () => {
const renderResult = render(<Button />);
const button = renderResult.queryByRole("button");
expect(button).toHaveStyleRule("color", "orange", {
modifier: css`
${Span}
`
});
});
このようなケースもスコープ使用なコンポーネントのルート要素からmodifier
を通してテストできます。その場合はstyled-components
が提供するcss
Tagged template を用いてセレクタを書きます。
リポジトリ
上記の内容はこのリポジトリをローカルにgit clone
し、yarn && yarn test
と叩くことで実際にテストを走らせれます。