Search code examples
react-nativeexpots-jest

Test react-native app with 'jest-expo' preset trying to import a file after the Jest environment has been torn down


I'm trying to implement test for my react native app using expo.

I would like to test a simple component that import expo library (@expo/vector-icons) :

const Icon: FC<IconProps> = (props: IconProps) => {
    const colors = useColors();
    const IconComponent = createIconSetFromIcoMoon(
        require("../../../../assets/icons/selection.json"),
        'IcoMoon',
        'icomoon.ttf'
    );

    return (
        <IconComponent name={props.name} size={props.size || 20} color={props.color || colors.label}/>
    );
};

Here is my test:

const iconProps = {
    name: "alert-circle",
    size: 20
}

describe("<Icon/>", () => {
    describe("Rendering", () => {
        it("render default as expected", () => {
            const icon = create(<Icon {...iconProps}/>)

            expect(icon.toJSON()).toMatchSnapshot();
        })
    })
})

But i got an error :

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 Object.get [as Text] (node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/lib/react-native.js:13:26)
  at Icon.render (node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/lib/create-icon-set.js:120:58)

Here is my jest configuration :

preset: 'jest-expo',
setupFiles: [
        "<rootDir>/jest/setupJestMock.ts"
    ],
testEnvironment: "node",
transform: {
        '^.+\\.ts?$': 'ts-jest',
    },
transformIgnorePatterns: [
        "node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|@sentry/.*)"
    ],

I've tryed to add :

jest.useFakeTimers();

In my setupJestMock.ts file but nothing changed.

What i am doing wrong ? Note that i'm using typescript.


Solution

  • I have the same error with jest and custom icon moon

    Details:
    
    node_modules/@expo/vector-icons/createIconSetFromIcoMoon.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import createIconSetFromIcoMoon from './build/createIconSetFromIcoMoon';
                                                                                        ^^^^^^
    
    SyntaxError: Cannot use import statement outside a module                                                                                      ^^^^^^
    
        SyntaxError: Cannot use import statement outside a module
    

    and I fixed the error following the jest expo docs.

    I updated the transformIgnorePatterns on my jest.config.js file

      "transformIgnorePatterns": [
        "node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg)"
      ]
    

    I encountered another error

    ● Test suite failed to run
    
    TypeError: Cannot read properties of undefined (reading 'Expo')
    
        8 |   MaterialIcons,
        9 | } from '@expo/vector-icons';
    > 10 | import createIconSetFromIcoMoon from '@expo/vector-icons/createIconSetFromIcoMoon';
    

    solved with mocking the function on jest.setup.js

    // Mock createIconSetFromIcoMoon to solve the error
    jest.mock('@expo/vector-icons/createIconSetFromIcoMoon', () => {
      return jest.fn();
    });