【create-react-app】jestでuuidを利用するコンポーネントのテストをする
create-react-appではテストランナーにjestが利用されています。
今回、uuidを利用するコンポーネントでスナップショットテストを書く際に少し調べたのでまとめます。
こちらのissueでいろいろ話されていますが、jest.mock
を使うやり方が良さそう。
サンプルのアプリケーションを作成してまとめます。
プロジェクトを作成して、uuidのパッケージを追加。App.jsx(App.js)を下記のように修正します。
import React from 'react'; import './App.css'; import { v4 as uuid } from 'uuid'; function App() { return ( <div className="App"> <p>{uuid()}</p> </div> ); } export default App;
App.test.jsxを下記のように修正。
import React from 'react'; import { render } from '@testing-library/react'; import App from './App'; test('renders currently', () => { const {container} = render(<App />); expect(container).toMatchSnapshot(); });
一度、testを実行します。
$ yarn run test
こんな感じで通るかと思います。
PASS src/App.test.jsx ✓ renders currently (18ms) › 1 snapshot written. Snapshot Summary › 1 snapshot written from 1 test suite. Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 1 written, 1 total Time: 1.409s Ran all test suites related to changed files. Watch Usage › Press a to run all tests. › Press f to run only failed tests. › Press q to quit watch mode. › Press p to filter by a filename regex pattern. › Press t to filter by a test name regex pattern. › Press Enter to trigger a test run.
ただ、uuidを利用したコンポーネントのため、都度値が変わります。そのため、再度testを実行すると当然ですが失敗します。
FAIL src/App.test.jsx ✕ renders currently (6ms) ● renders currently expect(received).toMatchSnapshot() Snapshot name: `renders currently 1` - Snapshot + Received <div> <div class="App" > <p> - 12fa6ae8-75d3-40b3-97af-172d0a304d37 + 19c42b95-7fcc-4848-9616-4396f6c768e5 </p> </div> </div> 5 | test('renders currently', () => { 6 | const {container} = render(<App />); > 7 | expect(container).toMatchSnapshot(); | ^ 8 | }); 9 | at Object.<anonymous> (src/App.test.jsx:7:21) › 1 snapshot failed. Snapshot Summary › 1 snapshot failed from 1 test suite. Inspect your code changes or press `u` to update them. Test Suites: 1 failed, 1 total Tests: 1 failed, 1 total Snapshots: 1 failed, 1 total Time: 0.182s, estimated 1s Ran all test suites.
toMatchSnapshot()を使ったtestがはじめて実行された場合、src配下の__snapshots__
にスナップショットファイルが生成されます。
中身を見ると、初回実行時に対象のコンポーネントのレンダリングされたDOMが書かれています。
// Jest Snapshot v1, https://goo.gl/fbAQLP exports[`renders currently 1`] = ` <div> <div class="App" > <p> 12fa6ae8-75d3-40b3-97af-172d0a304d37 </p> </div> </div> `;
二度目以降は、こいつと差分がある場合は落ちるという感じ。
対応は、テスト実行時に利用されるuuid生成の関数をモックにして、スナップショットと同じ固定値を返すようにしてあげます。
App.test.jsxを下記のように修正します。
import React from 'react'; import { render } from '@testing-library/react'; import App from './App'; jest.mock('uuid',() => ({ v4: () => '12fa6ae8-75d3-40b3-97af-172d0a304d37', })); test('renders currently', () => { const {container} = render(<App />); expect(container).toMatchSnapshot(); });
これでtestが通ります。 サンプルのプロジェクトは下記にあげました。