React + Jestでコンポーネントの分岐出力をテストする

条件分岐でコンポーネントの出し分けをしている時に正しくコンポーネントが出ているかどうかに使えるやつ
UI ロジックのリグレッションテストで使える
分岐結果の出力を見てるだけなのでテストとして壊れづらく、運用しやすいと考えている

確認環境

Next.js で確認してるけど素の React でも同じだと思う

EnvVer
@swc/core1.2.133
@swc/jest0.2.17
jest27.4.7
next12.0.8
react17.0.2
react-dom17.0.2
react-test-renderer17.0.2
typescript4.5.4

テスト対象

テストのためにコンポーネントを細かく export すると名前空間が汚染されるのが悩み…

type BaseProps = { id: string;
};
type SwitchExampleProps = BaseProps & { display: 'Foo' | 'Bar';
};
export const Foo = (props: BaseProps) => { return ( <div id={props.id}> <p>Foo</p> </div> );
};
export const Bar = (props: BaseProps) => { return ( <div id={props.id}> <p>Bar</p> </div> );
};
export const SwitchExample = (props: SwitchExampleProps) => { if (props.display === 'Foo') { return <Foo id={props.id} />; } else { return <Bar id={props.id} />; }
};

テストコード

react-testing-library の .toHaveAttribute().toHaveDisplayValue() を書き連ねるより圧倒的に楽で保守性も良いと思う

import TestRenderer from 'react-test-renderer';
import { Bar, Foo, SwitchExample } from './SwitchExample';
type TestCase = { name: string; param: Parameters<typeof SwitchExample>[0]; actual: JSX.Element;
};
describe('SwitchExample', () => { const testCaseItems: TestCase[] = [ { name: 'Foo', param: { id: 'hoge', display: 'Foo', }, actual: <Foo id={'hoge'} />, }, { name: 'Bar', param: { id: 'piyo', display: 'Bar', }, actual: <Bar id={'piyo'} />, }, ]; testCaseItems.forEach((item) => { // eslint-disable-next-line jest/valid-title it(`switched condition ${item.name}`, () => { const result = TestRenderer.create( <SwitchExample id={item.param.id} display={item.param.display} /> ); const actual = TestRenderer.create(<>{item.actual}</>); expect(result.toJSON()).toStrictEqual(actual.toJSON()); }); });
});

参考記事