Breathnote
React Testing Libraryのスナップショットテストで、Material-UIの属性値に差分が出る

React Testing Libraryのスナップショットテストで、Material-UIの属性値に差分が出る

Material-UIは、コンポーネントに一意のidclassaria-**属性を自動で付与しますが、これらの採番にはMath.randomが使われているようで、生成されるコードには、毎回差分が発生します。

上記の仕様は、スナップショットテストも例外でないため、テスト結果に影響を及ぼします。

テスト結果例
    <button
-     aria-controls="mui-31907"
+     aria-controls="mui-25430"
      aria-haspopup="true"
      aria-label="Menu"
      class="MuiButtonBase-root MuiIconButton-root"
-     id="mui-56827"
+     id="mui-85534"
      tabindex="0"
      title="Menu"
      type="button"
    >

発生する差分がclass属性だけであれば、こちらの方法で対処できますが、今回は、id属性とaria-controls属性が対象だったため、別のアプローチで解決する必要がありました。

対処法

renderの結果をDOM Stringに変換し、replaceメソッドで対象の属性を排除します。

Example.test.tsx
describe(`***`, () => {
  afterEach(cleanup)

  test('スナップショット', () => {
    const { container } = render(<DataGrid />)

    // https://github.com/mui-org/material-ui/issues/21293#issuecomment-654921524
    const tree = container.innerHTML.replace(/id="mui-[0-9]*"/g, '').replace(/aria-controls="(mui-[0-9]* *)*"/g, '')

    expect(tree).toMatchSnapshot()
  })
})

注意点として、スナップショットの結果を1行の文字列で返すようになるため、asFragmentよりもテスト結果が確認しづらくなります。

所感

本件では、ローカルの他に、GitHub Actionsでもテストを実施しており、jest -uで強引に更新したくなかったため、今回の措置を行いました。

テストの実施がローカルだけであれば、必要ない措置かもしれません。