react-native-vector-icons: react-native 0.64.0 - Jest testing fails when testing component with icon

Environment

react-native-vector-icons version: 8.1.0

System:
    OS: macOS 11.2.2
    CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
    Memory: 2.26 GB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 15.11.0 - /var/folders/n0/xlj5zhn56tl42517807ctnl40000gn/T/yarn--1616165407310-0.13720577253664556/node
    Yarn: 1.22.10 - /var/folders/n0/xlj5zhn56tl42517807ctnl40000gn/T/yarn--1616165407310-0.13720577253664556/yarn
    npm: 7.6.0 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.10.1 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 14.4, DriverKit 20.2, macOS 11.1, tvOS 14.3, watchOS 7.2
    Android SDK: Not Found
  IDEs:
    Android Studio: 4.1 AI-201.8743.12.41.7042882
    Xcode: 12.4/12D4e - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.10 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.1 => 17.0.1 
    react-native: 0.64.0 => 0.64.0 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Description

yarn test fails in brand new RN 0.64.0 project with icon added to App component. With RN 0.63.4 this works fine.

Demo

https://github.com/josmithua/react-native-0.64.0-jest-fail-with-rn-vector-icons (created with command: npx react-native init JestTest --template react-native-template-typescript)

  1. yarn
  2. yarn test

Output:

yarn run v1.22.10
$ jest
 FAIL  __tests__/App-test.tsx
  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    /Users/joshua/code/JestTest/node_modules/react-native-vector-icons/Ionicons.js:6
    import createIconSet from './lib/create-icon-set';
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      28 | } from 'react-native/Libraries/NewAppScreen';
      29 |
    > 30 | import Icon from 'react-native-vector-icons/Ionicons';
         | ^
      31 |
      32 | const Section: React.FC<{
      33 |   title: string;

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
      at Object.<anonymous> (App.tsx:30:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        1.792 s
Ran all test suites.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 7
  • Comments: 22

Most upvoted comments

Actually to get it to work, I had to also add @react-native to the pattern, so it looks like this:

"transformIgnorePatterns": [
  "node_modules/(?!(@react-native|react-native|react-native-vector-icons)/)"
]

Looks like the react-native team moved some of their code to a new package in v0.64.0, @react-native/polyfills, which needs transformed as well.

@josmithua I realized I’ve made a mistake. Basically I had a part of the jest configuration in package.json and a more detailed configuration in jest.config.es. I’ve removed the package.json part and left the jest config file. Thank you 😃

Now my jest.config.es :

module.exports = {
  preset: 'react-native',
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
  setupFilesAfterEnv: ['@testing-library/jest-native/extend-expect'],
  "transformIgnorePatterns": [
    "node_modules/(?!(@react-native|react-native|react-native-vector-icons)/)"
  ],
  reporters: [
    'default',
    [
      'jest-html-reporters',
      {
        filename: 'jest.report.html',
        expand: true
      }
    ]
  ]
};

Thanks, adding the following made it work:

"transformIgnorePatterns": [
  "node_modules/(?!(react-native|react-native-vector-icons)/)"
]

EDIT: Actually it didn’t, you need to add @react-native to the pattern. See my comment below

@pke I don’t fully understand what your jest setup is like but if you’re having trouble with testing a component with react-native-vector-icons/MaterialCommunityIcons then all you need is,

jest.mock(
  'react-native-vector-icons/MaterialCommunityIcons',
  () => 'MockedMaterialCommunityIcons',
);

What this simply says to jest is that to use a mock instead of the component returned by import Icon from 'react-native-vector-icons/MaterialCommunityIcons';.

After doing this you will see,

<MockedMaterialCommunityIcons
                name="information"
                size={32}
                color={color}
              />

in your snapshots and assert the props accordingly.

I have a feeling all the problems you are trying to describe here are due to a mixed-up configuration, lack of understanding of how the configurations work etc. Don’t just throw every suggestion you see on the internet at the problem.

@developerdanx1 This worked for me too. I removed some of the additional code you had, so mine ended up like this:

jest.config.js:

module.exports = {
  preset: 'react-native',
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
  transformIgnorePatterns: [
    'node_modules/(?!(@react-native|react-native|react-native-vector-icons)/)',
  ],
};

It would be nice if this tidbit was in the documentation!

@DeveloperDanX yes, this is still working for me.

Actually to get it to work, I had to also add @react-native to the pattern, so it looks like this:

"transformIgnorePatterns": [
  "node_modules/(?!(@react-native|react-native|react-native-vector-icons)/)"
]

Looks like the react-native team moved some of their code to a new package in v0.64.0, @react-native/polyfills, which needs transformed as well.

Hi @josmithua , is this still working ? I have the same problem when trying to test a component that has an Icon children. 😦

PS: I’ve tried your solution, and no success.