how to configure jest with webpack, node_modules and scss - reactjs

Update: edited jest config in package.json to include identity-obj-proxy and added transform-es2015-modules-commonjs to .babelrc
Trying to setup jest and enzyme to run unit tests on a React.js project. This configuration setting works fine as long as I'm not requiring a node_module in the target component. But if the component I want to test imports a node_module that itself imports a scss file it throws this error:
import('../../scss/bulkAction.scss');
^^^^^^
SyntaxError: Unexpected token import
This is my jest config file:
"jest": {
"testPathIgnorePatterns": [
"<rootDir>/(node_modules)"
],
"moduleFileExtensions": [
"js",
"jsx"
],
"moduleDirectories": [
"node_modules"
],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/app/_tests_/config/fileMock.js",
"\\.(css|scss)$": "identity-obj-proxy"
},
"transform": {
"^.+\\.(js|jsx)$": "babel-jest",
"^.+\\.(css|scss)$": "<rootDir>/app/_tests_/config/scssTransform.js",
"^(?!.*\\.(js|jsx|json)$)": "<rootDir>/app/_tests_/config/fileTransform.js"
}
},
this is my .babelrc file
{
"presets": [
["es2015", {"modules": false}], "react", "stage-0"],
"env": {
"start": {
"presets": [
"react-hmre"
]
},
"test": {
"presets": ["es2015", "react", "stage-0"],
"plugins": ["transform-es2015-modules-commonjs"]
}
}
}
I've tried multiple different configurations and have been reading the docs for quite awhile and haven't been able to solve this problem. I'm hoping someone can help!
Note about our file structure:
/WebApps/ProjectName/ProjectFolder/app
/WebApps/ProjectName/ProjectFolder/package.json
/WebApps/ProjectName/ProjectFolder/.babelrc
/WebApps/ProjectName/ProjectFolder/node_modules
I add this just incase the file pathing of the may be part of the problem.

You've missed probably transform-es2015-modules-commonjs babel plugin.
Add this to your .babelrc
// .babelrc
{
"presets": [
["es2015", {"modules": false}]
],
"env": {
"test": {
"plugins": ["transform-es2015-modules-commonjs"]
}
}
}
Remember to install this plugin before using:
babel-plugin-transform-es2015-modules-commonjs --save-dev
When you run your tests with jest, it set the environment as test by default.
In my project I use also identity-obj-proxy, like:
// jest.config.json
{
"moduleNameMapper": {
"\\.(css|scss)$": "identity-obj-proxy"
},
}
Also, first install it before using:
npm install --save-dev identity-obj-proxy
I highly recommend reading the page from official jest documentation about integration jest with webpack.
https://facebook.github.io/jest/docs/webpack.html#mocking-css-modules
https://facebook.github.io/jest/docs/webpack.html#using-with-webpack-2

Related

Jest Cannot use import statement outside a module [duplicate]

If I use import/export from ES6 then all my Jest tests fail with error:
Unexpected reserved word
I convert my object under test to use old school IIFE syntax and suddenly my tests pass. Or, take an even simpler test case:
var Validation = require('../src/components/validation/validation'); // PASS
//import * as Validation from '../src/components/validation/validation' // FAIL
Same error. Obviously there's a problem with import/export here. It's not practical for me to rewrite my code using ES5 syntax just to make my test framework happy.
I have babel-jest. I tried various suggestions from GitHub issues. It is no go so far.
File package.json
"scripts": {
"start": "webpack-dev-server",
"test": "jest"
},
"jest": {
"testPathDirs": [
"__tests__"
],
"testPathIgnorePatterns": [
"/node_modules/"
],
"testFileExtensions": ["es6", "js"],
"moduleFileExtensions": ["js", "json", "es6"]
},
File babelrc
{
"presets": ["es2015", "react"],
"plugins": ["transform-decorators-legacy"]
}
Is there a fix for this?
From my answer to another question, this can be simpler:
The only requirement is to configure your test environment to Babel, and add the ECMAScript 6 transform plugin:
Step 1:
Add your test environment to .babelrc in the root of your project:
{
"env": {
"test": {
"plugins": ["#babel/plugin-transform-modules-commonjs"]
}
}
}
Step 2:
Install the ECMAScript 6 transform plugin:
npm install --save-dev #babel/plugin-transform-modules-commonjs
And that's it. Jest will enable compilation from ECMAScript modules to CommonJS automatically, without having to inform additional options to your jest property inside package.json.
UPDATE 2020 - native support of ECMAScript modules (ESM)
According to this issue, there is native support of ESM from jest#25.4.0. So you won't have to use babel anymore. At the time of writing this answer (05/2020), to activate that you need to do three simple things:
Make sure you don't transform away import statements by setting transform: {} in config file
Run node#^12.16.0 || >=13.2.0 with --experimental-vm-modules flag
Run your test with jest-environment-node or jest-environment-jsdom-sixteen.
So your Jest configuration file should contain at least this:
export default {
testEnvironment: 'jest-environment-node',
transform: {}
...
};
And to set --experimental-vm-modules flag, you will have to run Jest as follows:
node --experimental-vm-modules node_modules/jest/bin/jest.js
Also note in the Github issue that this approach does not yet support the jest object. So you may need to import it manually:
import {jest} from '#jest/globals'
(I hope this will change in the future)
For an updated configuration, I'm using https://babeljs.io/setup#installation
Select JEST and be happy:
As a reference, the current configuration:
npm install --save-dev babel-jest
In your package.json file, make the following changes:
{
"scripts": {
"test": "jest"
},
"jest": {
"transform": {
"^.+\\.jsx?$": "babel-jest"
}
}
}
Install babel preset:
npm install #babel/preset-env --save-dev
Create a .babelrc file:
{
"presets": ["#babel/preset-env"]
}
Run your tests:
npm run test
In package.json, kindly set like this one: "test": "node --experimental-vm-modules node_modules/.bin/jest"
Should be good!
It's a matter of adding stage-0 to your .babelrc file. Here is an example:
{
"presets": ["es2015", "react", "stage-0"],
"plugins": ["transform-decorators-legacy"]
}
I encountered the same issue.
These are what I did:
yarn add --dev babel-jest #babel/core #babel/preset-env
Make file jest.config.js in rootDir.
module.exports = {
moduleFileExtensions: ["js", "json", "jsx", "ts", "tsx", "json"],
transform: {
'^.+\\.(js|jsx)?$': 'babel-jest'
},
testEnvironment: 'node',
moduleNameMapper: {
'^#/(.*)$': '<rootDir>/$1'
},
testMatch: [
'<rootDir>/**/*.test.(js|jsx|ts|tsx)', '<rootDir>/(tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx))'
],
transformIgnorePatterns: ['<rootDir>/node_modules/']
};
Then make file babal.config.js in rootDir.
Go like this:
module.exports = {
"presets": ["#babel/preset-env"]
}
Below is how I setup jest, typescript and ES Modules for my project.
jest.config.js
/**
* #type {import('ts-jest/dist/types').InitialOptionsTsJest}
* To configure ESM support, see: https://kulshekhar.github.io/ts-jest/docs/guides/esm-support
*
**/
export default {
preset: 'ts-jest/presets/default-esm',
testEnvironment: 'node',
extensionsToTreatAsEsm: ['.ts'],
globals: {
'ts-jest': {
useESM: true
}
},
setupFiles: ['<rootDir>/__tests__/setup.ts'],
};
tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"outDir": "./dist",
"moduleResolution": "node",
// "strict": true,
"esModuleInterop": true,
"inlineSourceMap": true,
}
}
package.json scripts and devDependencies
"scripts": {
"start": "node ./dist/server.js",
"dev": "tsc-watch --onSuccess \"node ./dist/server.js\"",
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest"
},
"devDependencies": {
"#jest/globals": "^27.4.4",
"#types/express": "^4.17.13",
"#types/jest": "^27.4.0",
"#types/supertest": "^2.0.11",
"cross-env": "^7.0.3",
"supertest": "^6.2.1",
"ts-jest": "^27.1.3"
}
__tests__/setup.ts
import dotenv from 'dotenv';
dotenv.config({
path: './.env.test'
});
all is explained in the jest docs: jest docs
1.
npm install --save-dev babel-jest #babel/core #babel/preset-env
in file: babel.config.js
module.exports = {
presets: [['#babel/preset-env', {targets: {node: 'current'}}]],
};
In addition to installing babel-jest (which comes with Jest by default now) be sure to install regenerator-runtime.
To add support for React and react-testing-library it may be useful to eject CreateReactApp and take all needed Jest configuration from the package.json. It is ready to use with another bundler, Rollup in my case.

create-react-app jest encountered unexpected token {

I'm developing a React app with a QR-scanner in it with create-react-app.
I've added the module react-qr-reader which in turn uses the modules webrtc-adapter.
It all works great, until I run yarn test. Then it shows me this error:
I've already ejected the project so I can use transformIgnorePatterns and added node_modules/webrtc-adapter to the array, but that still results in the same error.
Can anyone help me with this?
If you don't want to eject from Create-React-App you can use the CLI in your package.json to override 'transformIgnorePatterns'.
Reference - https://github.com/facebook/create-react-app/issues/2537#issuecomment-390341713
"scripts": {
"test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!your-module-name)/\"",
},
It's because of de ES6 syntax in a package into node_modules, you need to config the "transformIgnorePatterns" to transform this package.
The issue on Jest: https://github.com/facebook/jest/issues/2081
How to configure: http://facebook.github.io/jest/docs/tutorial-react-native.html#transformignorepatterns-customization
"transformIgnorePatterns": [
"node_modules/(?!(react-qr-reader)/)"
]
if this doesn't work, use the babel.config.js with this configuration (is important the file ".js", this configuration don't work in ".babelrc" file):
module.exports = {
presets: [
[
"#babel/preset-env",
{
"modules": "commonjs",
"debug": false
}
],
/// your presets
],
plugins: [
//... your plugins
]
};

"unexpected token import" error while running tests

when I run the test, I get the following error:
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import React from 'react';
^^^^^^
SyntaxError: Unexpected token import
It makes sense, since all the lines of "import React" or "import Enzyme", are marked as an error by ESlint. I don´t know why.
This is my .babelrc file:
{
"presets": [
"react",
"stage-2",
["env", {
"test": {
"presets": ["env", "react", "stage-2"],
"plugins": ["transform-export-extensions"],
"only": [
"./**/*.js",
"node_modules/jest-runtime"
]
},
"targets": {
"browsers": ["last 2 versions", "safari >= 7"]
},
"modules": false
}]
]
}
If you are using babel 6 and jest 24 then be informed that jest 24 has dropped support for babel 6.
There are two solutions
Upgrade your app to babel 7. (actively maintained by its developers)
If you don't want to upgrade, make sure that you stick on jest 23.
There is one more work around if you want to use jest 24. Use babel-jest locked at version 23.
"dependencies": {
"babel-core": "^6.26.3",
"babel-jest": "^23.6.0",
"babel-preset-env": "^1.7.0",
"jest": "^24.0.0"
}
Hello dev can you try,
install babel-jest
set this inside .babelrc
"env": {
"test": {
"presets": ["es2015", "react"],
"plugins": ["syntax-object-rest-spread", "transform-es2015-modules-commonjs"]
},
testing with jest

How to use Karma and Jest together in unit testing React application?

I am testing a React application already developed. The application has some unit test cases written in Karma but I am going to use Jest to unit test the application as it is the new framework, developed by facebook for testing React. The problem I am facing is because of file .babelrc. For Jest to run fine the content of .babelrc file should be as follows:
// .babelrc
{
"presets": ["es2015", "react"]
}
But my existing application uses Karma and has the babelrc file content as below:
{
"presets": [
"es2015",
"react",
"stage-0"
]
, "plugins": [
"transform-object-rest-spread"
, "transform-decorators-legacy"
, "transform-es2015-modules-amd"
]
}
The current babelrc file is not allowing Jest to run properly and causes error. But the thing is I cant modify its content as required by Jest since it will hamper my Karma test cases to stop running. Is there a way I can use the both at same time until i rewrite existing test cases in Jest?
I was able to run both Karma and Jest together so thought of sharing. I configured the babelrc file as follows:
{
"env": {
"test": {
"presets": [
"es2015",
"react"
]
},
"development": {
"presets": [
"es2015",
"react"
],
"plugins": [
............
]
},
"production": {
"presets": [
"es2015",
"react"
],
"plugins": [
...............
]
}
}
}

Node app fails with SyntaxError: Unexpected token '...'

Using Babel and Webpack to build a React application.
During the build process, it fails with SyntaxError: Unexpected token ...
Babel 6 introduced a change to no longer transpile ES2015 by default. See more detail here: https://babeljs.io/blog/2015/10/29/6.0.0
To fix this, edit your package.json or .babelrc file to include { "presets": ["es2015"] }
Here's an example of the section of my package.json file with the fix:
"webpack-hot-middleware": "^2.10.0",
"webpack-middleware": "^1.5.1"
},
"babel": {
"presets": [
"react",
"node5",
"stage-0",
"es2015"
],
"env": {
"test": {
"plugins": [
"rewire"
]
}
}
},
"eslintConfig": {

Resources