自分のサイトでも入れようと思い、インストールしました。ところが、導入まではうまくいったものの、Jest(Testing Library を使ってます)が通らなくなりました。なんでやねん。
Using the "styled" tag in runtime is not supported.
...などというエラーが出ました。調べてみるとどうも根が深そう。
調査を進めていくうちに下記の投稿を発見(こういう調査は毎回骨が折れる)
という理解です。そうすることで、Jest を実行した時に Linaria で指定したタグ名が返ってくるので、これを Testing Library がタグとして認識します。
タグとして認識できれば、どのような要素なのかが判別でき、Role なども判別できますね。
コード例
テストしたいコンポーネント
これは実際に当ブログで使われている Footer の Component です。単純にコピーライトと名前が入っています。
import React from 'react';
import { StyledFooter } from './styledFooter'; // Linaria が使われてる CSS in JS を分割したもの
const Footer: React.FC = () => {
return <StyledFooter>© 2021 HOSONOKOTARO Tech Blog</StyledFooter>;
};
export default Footer;
テスト
期待したい結果として、Role が contentinfo のものの中に、指定したテキストが存在するか?というものです。必要な処理は通常のテストコードに加えて mock 関数が挟まってます(詳しくは後述)
import '@testing-library/jest-dom/extend-expect';
import { render, screen } from '@testing-library/react';
import React from 'react';
import Footer from './Footer';
jest.mock('@linaria/react', () => {
const styled = (tag: string | number | symbol) => {
return jest.fn(() => tag.toString());
};
return {
styled: new Proxy(styled, {
get(o, prop) {
return o(prop);
},
}),
};
});
it('it should render: Footer', () => {
render(<Footer />);
expect(screen.getByRole('contentinfo')).toHaveTextContent(
'© 2021 HOSONOKOTARO Tech Blog'
);
});
解説
テストコードの中にあるjest.mock()
で Linaria のライブラリを Wrap します。これでstyled.div
などの処理が mock 化されます。
その際にタグ名を取得したいので関数内にnew Proxy()
を記載し、入ってくるタグ名を傍受します。
これでタグ名が取得できるのでjest.fn()
でタグ名を return します。すると、次のようにタグ名が正しく取得できます。
footer の Role は contentinfo なので、それも正しく認識していますね。あとはテストしていくだけ。