styled-componentsで作ったコンポーネントをjest + enzymeでテストする時は dive() を使う
Pathee エンジニアの keisei1092 です。
styled-componentsで作ったコンポーネントをはさんだコンポーネントをテストする時のやり方に若干戸惑いました。
次のように Wrapper
というstyled-componentsで定義されたコンポーネントに囲まれた Test
コンポーネントがあるとします。
import React from 'react'; import { pure } from 'recompose'; import styled from 'styled-components'; const Wrapper = styled.div` display: flex; align-items: center; `; // ... 何かスタイルを定義 export type Props = { title: string; }; export const Test = ({ title }: Props) => ( <Wrapper> <h1>{title}</h1> </Wrapper> ); export default pure(Test);
このとき、 props.title
に渡した値が正しくレンダリングされることをテストしたいとします。あまり深く考えず次のようなテストコードを書いてみます。
import React from 'react'; import { shallow } from 'enzyme'; import Test, { Props } from '@app/components/Test'; describe('<Test>', () => { let props: Props; beforeEach(() => { props = { title: 'title' }; }); describe('rendering', () => { it('should render title', () => { const wrapper = shallow(<Test {...props} />); const h1 = wrapper.find('h1'); expect(h1.text()).toEqual(props.title); }); }); });
これを実行すると
Method “text” is meant to be run on 1 node. 0 found instead.
とエラーが出てテストにfailします。
shallowで <Test />
をレンダリングしているところをデバッグしてみます。
console.log test/components/CollectionRegister/SRHeader/test.spec.tsx:20 <Component title="title" />
Wrapper
がレンダリングされていることはわかります( Component
という表示で Wrapper
と実際の名前は出ていない)が、その先の <h1>
以降がレンダリングされていないようです。ここで、enzymeの dive() を使います。
describe('rendering', () => { it('should render title', () => { const wrapper = shallow(<Test {...props} />); const h1 = wrapper.dive().find('h1'); // changed expect(h1.text()).toEqual(props.title); }); });
これを実行してみます。
PASS test/components/test.spec.tsx <Test> rendering ✓ should render title (18ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 2.945s, estimated 3s Ran all test suites matching /test\/components\/test.spec.tsx/i. ✨ Done in 4.01s.
無事テストがパスしました。
ちなみに先ほどのコンポーネントを console.log(wrapper.dive().debug());
でデバッグすると次のように出力されます。
console.log test/components/test.spec.tsx:20 <styled.div> <h1> title </h1> > </styled.div>
<Test />
でレンダリングしているコンポーネントが正しく出力されています。
styled-components jest enzyme test
などで検索しましたが英語のページばかりで日本語のページが見つけられなかったので逆引きとして使えるように書いてみました。
英語の習熟の大事さをひしひしと感じます。