Jestのスナップショットテストでreact-native-vector-iconsがエラーを起こす問題の解決


前提

  • ReactNative: 0.63.2
  • expo: 39.0.0
  • jest: 25.1.0
  • jest-expo: 40.0.1

起きている問題

  • スナップショットテストを書いていて、 jest を実行したところ、以下のようなエラーが発生した。
ReferenceError: You are trying to `import` a file after the Jest environment has been torn down.

      at Object.get Text [as Text] (node_modules/react-native/index.js:122:12)
      at Icon.render (node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/lib/create-icon-set.js:120:58)
      at finishClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7693:31)
      at updateClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7648:24)
      at beginWork$1 (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9159:16)

中略

    Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

    Check the render method of `Icon`.
        in Icon (created by Icon)
        in Icon (created by MaterialIcon)
        in MaterialIcon (created by FoodMediumItem)

テストコードは以下

import React from 'react';
import renderer from 'react-test-renderer';
import { FoodMediumItemStory } from './stories';

it('renders correctly', () => {
  const tree = renderer.create(<FoodMediumItemStory />).toJSON();
  expect(tree).toMatchSnapshot();
});

原因

  • react-native-vector-iconsがObjectをreturnしていて、 React.createElement の正しい返り値になっていない模様。(ちゃんとソースコードまで読んでいない)

解決方法

react-native-vector-icons をmock化する。テストコードを以下のように変更した。

import React from 'react';
import renderer from 'react-test-renderer';
import { FoodMediumItemStory } from './stories';

jest.mock('react-native-vector-icons/MaterialIcons', () => 'Icon'); //これを追加

it('renders correctly', () => {
  const tree = renderer.create(<FoodMediumItemStory />).toJSON();
  expect(tree).toMatchSnapshot();
});

参考文献

react-native-vector-icons/MaterialIcons jest-expo snapshot test error with typescript