ReferenceError: React is not defined in jest tests
Asked Answered
H

7

47

I have the following line that executes correctly in browser

eval(Babel.transform(template, { presets: ['react'] }).code);

but when I run jest tests I am getting ReferenceError: React is not defined

What am I missing?

More info: in the test file I have the following:

const wrapper = shallow(<MyComponent/>);
const instance = wrapper.instance();
instance.componentFunction(...)

and then the componentFunction has the eval(Babel.transform(template, { presets: ['react'] }).code); line where template is something it gets from the test file and can be something like <span>...</span>

Please let me know if more details are needed

Heliotype answered 21/11, 2019 at 17:51 Comment(0)
G
53

@babel/preset already has support for what you need. According to the react 17 documentation I only had to set the runtime to automatic in my babel.config.json.

{
  "presets": [
    ["@babel/preset-react", {
      "runtime": "automatic"
   }]
  ]
}

If you are using @babel/plugin-transform-react-jsx the config should be

{
  "plugins": [
    ["@babel/plugin-transform-react-jsx", {
      "runtime": "automatic"
    }]
  ]
}

The latter is usually not needed since @babel/preset-react includes @babel/plugin-transform-react-jsx.


Why you shouldn't use import React from 'react';

The documentation states:

There is also a technical RFC that explains how the new transformation works.

If you want to upgrade. React also provides an automated script that removes unnecessarry imports from your code.

Glandule answered 4/11, 2021 at 5:44 Comment(1)
For React Native, importing SVG's in test and using TS for tests, the first noted solution worked for me.Frightful
C
25

Personally I stumbled upon this problem when dealing with Next.js (configured as jsx: 'preserve'). If this is a problem with jest working in a Next.js like environment you can configure your babel used by Jest in the same way:

Since next.js already includes the next/babel preset dependency you may as well use and have a setup more consistent with your next.js environment.

babel.config.js:

module.exports = {
  presets: ['next/babel']
};

Alternatively, if anyone experienced this bug had the problem wherein import React from 'react' is not necessary, because it is already included globally and doesn't need to be included in every file, then this solution may work for you. This may also just be helpful for you if you ever need to import or define global functions for jest.

I simply configured React to be globally defined in jest.

My jest.config.js:

module.exports = {
  moduleDirectories: ['./node_modules', 'src'],
  // other important stuff
  setupFilesAfterEnv: ['<rootDir>/src/jest-setup.ts']
}

My src/jest-setup.ts (or make an equivalent jest-setup.js):

import '@testing-library/jest-dom';
import React from 'react';

global.React = React; // this also works for other globally available libraries

Now I don't need to worry about each file importing React (even though eslint knows that's unnecessary with Next.js)

Comprador answered 12/10, 2021 at 16:43 Comment(1)
thank you. it was a good workaround in my situationPopulace
I
18

If you are using JSX in your jest test files, you will need to add the following import line to the top of the file:

import React from 'react';

The reason for this is that Babel transforms the JSX syntax into a series of React.createElement() calls, and if you fail to import React, those will fail.

Insurrection answered 21/11, 2019 at 17:54 Comment(5)
I do have import React from 'react'; in the .test fileHeliotype
You need also to have it in the component file. E.g., import React, { Component } from "react"; At least, this fixed the issue for me.Ripuarian
@HawkeyeParker's answer fixed the issue for me - will be including the react import now on any components ( I use next.js so didn't think I had to )Pterodactyl
Is there any way to avoid having to import it everywhere if we don't need it? For functional components you don't even use it, the app works fine without importing it, the only problem is jestBoone
@Boone Depending on your setup you can change your compiler transform configuration. See reactjs.org/blog/2020/09/22/… for the most common ones. René Link's answer alludes to Babel, which is one of the most commonCrosspollination
B
0

This happened to me after react-native and jest and other node_modules related to unit test were upgraded. Here is my working config:

jest.config.js

module.exports = {
  preset: 'react-native',
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
  moduleDirectories: ['./node_modules', 'src'],
  cacheDirectory: '.jest/cache',
  transformIgnorePatterns: [
    '<rootDir>/node_modules/(?!@react-native|react-native)',
  ],
  moduleNameMapper: {
    '^[./a-zA-Z0-9$_-]+\\.svg$': '<rootDir>/tests/SvgStub.js'
  },
  setupFiles: ['./jest-setup.js'],
  modulePathIgnorePatterns: ['<rootDir>/packages/'],
  watchPathIgnorePatterns: ['<rootDir>/node_modules'],
}

For setup file I had to use project specific one ./jest-setup.js but for a general use './node_modules/react-native-gesture-handler/jestSetup.js' should work too.

babel.config

{
    presets: ['module:metro-react-native-babel-preset'],
    plugins: [
    'react-native-reanimated/plugin'
  ]
};

Sources: https://github.com/facebook/jest/issues/11591#issuecomment-899508417

More info about the dependencies here: https://mcmap.net/q/372388/-jest-encountered-an-unexpected-token-with-react-native

Bloomy answered 1/11, 2022 at 13:38 Comment(0)
Y
0

If you are storing test data in separate test data files that contain JSX, you will also need to import react, as your file contains JSX and so results in a ReferenceError: React is not defined in jest tests error.

const testData = {
  "userName": "Jane Bloggs",
  "userId": 101,
  "userDetailsLink": <a href="details/101">Jane Bloggs</a>
};

importing react, as below, resolves the error.

import React from "react";

const testData = {
  "userName": "Jane Bloggs",
  "userId": 101,
  "userDetailsLink": <a href="details/101">Jane Bloggs</a>
};
Yusuk answered 18/1, 2023 at 13:58 Comment(1)
For me this was not working until I added import React from 'react'; and global.React = React; to jest.config.jsBaedeker
A
0

my package.json is below, and I use guide from @Zargold above. Add React to setupTests.js

"dependencies": {
  "ajv": "6.12.0",
  "autoprefixer": "^9.1.0",
  "axios": "^0.21.1",
  "babel-cli": "^6.26.0",
  "babel-core": "^6.26.3",
  "babel-eslint": "^7.2.3",
  "babel-loader": "^7.1.5",
  "babel-plugin-async-to-promises": "^1.0.5",
  "babel-plugin-transform-runtime": "^6.23.0",
  "babel-polyfill": "^6.26.0",
  "babel-preset-env": "^1.7.0",
  "clean-webpack-plugin": "^0.1.16",
  "copy-webpack-plugin": "^4.5.2",
  "cross-env": "^5.2.0",
  "css-loader": "^1.0.0",
  "eslint": "^4.2.0",
  "eslint-loader": "^1.9.0",
  "eslint-plugin-react": "^7.1.0",
  "express": "4.17.1",
  "extract-loader": "^2.0.1",
  "file-loader": "^1.1.11",
  "html-loader": "^0.5.5",
  "html-webpack-plugin": "^3.2.0",
  "postcss-loader": "^2.1.6",
  "react": "16.13.1",
  "react-dom": "16.13.1",
  "react-notifications": "^1.7.4",
  "react-redux": "7.2.0",
  "react-router": "5.1.2",
  "react-router-dom": "5.1.2",
  "react-scripts": "^5.0.1",
  "redux": "4.0.5",
  "sass": "^1.71.1",
  "sass-loader": "^7.1.0",
  "style-loader": "^0.21.0",
  "webpack": "4.42.1",
  "webpack-cli": "3.3.11",
  "webpack-dev-middleware": "3.7.2",
  "webpack-dev-server": "3.10.3",
  "webpack-hot-middleware": "2.25.0",
  "webpack-merge": "4.2.2"
},
"devDependencies": {
  "@testing-library/jest-dom": "^6.4.2",
  "@testing-library/react": "^12.1.5",
  "babel-plugin-transform-class-properties": "^6.24.1",
  "babel-plugin-transform-object-rest-spread": "^6.26.0",
  "babel-preset-react": "^6.24.1",
  "babel-register": "^6.26.0",
  "extract-text-webpack-plugin": "^4.0.0-beta.0",
  "uglifyjs-webpack-plugin": "^1.2.7"
}
Aftershock answered 10/4 at 14:56 Comment(2)
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From ReviewHautbois
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Doggery
C
0

In my case, I had to import react in my test in a way:

import * as React from 'react';

AND NOT LIKE THIS

import React from 'react';
Coldiron answered 31/5 at 9:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.