ES6 breaking your Jest tests?
Jest is a library for testing JavaScript code. For me, the biggest benefit of Jest is that it works without having to interact with other testing libraries. Developed by Fcebook, it’s also well suited for React code testing. I like it.
However, as Jest runs off node, if you’ve tried to use Jest to test code that depends on libaries using ES6 code, you have likely run into trouble. Most common is when using dependencies which use ES6 modules.
In my case, I used the Create React Application to seed my project. This gives all the basics to get started however you will need to perform some extra steps to get up and running. If you don’t use the CRA then the configuration files should still be similar.
Steps to Configure
To do this requires the use npm run eject
. This will destroy the dependency on the Create React App library. This is a one way operation.
npm run eject
inside the root of your project. This will create a number of configuration scripts which can be used to run the application. Remove the Jest and Babel configurations from the project’spackage.json
.- Upgrade babel. The easist way to do this is to use the Babel-Upgrade tool. This can be found at https://github.com/babel/babel-upgrade. Remove any remaining references to Babel 6.
- Delete the
node_modules
directory and reinstall the updated dependencies runningnpm install
- In the root of your project create the following two files:
-
/babel.config.js ([contents](#babel.config.js)) -
/jest.config.js ([contents](#jest.config.js))
-
- Run the following command to install the required babel plugins and settings:
npm install --save-dev @babel/preset-react @babel/preset-env @babel/plugin-transform-modules-commonjs @babel/plugin-syntax-dynamic-import @babel/plugin-syntax-import-meta @babel/plugin-proposal-class-properties @babel/plugin-proposal-json-strings
- In the
config/jest
directory create the following files:-
/config/jest/setupTests.js ([contents](#contents.js)) -
/config/jest/typescriptTransform.js ([contents](#typescriptTransform.js)) -
/config/jest/cssTransform.js ([contents](#cssTransform.js))
-
- Remove any unused files from the
config/jest
directory. If it’s not specified in thejest.config.js
file then it’s not used.
File Contents
/babel.config.js
The contents of the babel.config.js file should be as follows:
'use strict';
module.exports = {
env: {
test: {
presets: [
['@babel/preset-env',
{
debug: true,
modules: "commonjs"
}],
'@babel/preset-react',
],
plugins: [
"@babel/plugin-transform-modules-commonjs",
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-syntax-import-meta",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-json-strings"
],
},
},
};
/jest.config.js
Assuming your tests are in the <PROJECT_ROOT>/test
directory. The contents of the jest.config.js file should be as follows:
'use strict';
module.exports = {
"testEnvironment": "jsdom",
"setupFilesAfterEnv": [
"<rootDir>/config/jest/setupTests.js"
],
"coverageReporters": [
"lcov"
],
"collectCoverageFrom": [
"<rootDir>/src/**/?(*.)+(spec|test).[jt]s?(x)",
"!<rootDir>/test/**/?(*.)+(spec|test).[jt]s?(x)",
"!<rootDir>/src/**/*.d.ts"
],
"coverageThreshold": {
"global": {
"branches": 75,
"functions": 80,
"lines": 80,
"statements": 80
}
},
"testMatch": [
"<rootDir>/test/**/?(*.)+(spec|test).[jt]s?(x)"
],
"transform": {
"^.+\\.(js|jsx|mjs)$": "<rootDir>/node_modules/babel-jest",
"^.+\\.(tsx|ts|js|jsx)$": "<rootDir>/config/jest/typescriptTransform.js",
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js"
},
"transformIgnorePatterns": [
],
"moduleNameMapper": {
"@src/(.*)": "<rootDir>/src/$1",
"@test/(.*)": "<rootDir>/test/$1"
},
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"css",
"node"
]
}
/config/jest/setupTests.js
(Assuming you are using Enzyme)
'use strict';
const Enzyme = require('enzyme');
const Adapter = require('enzyme-adapter-react-16');
Enzyme.configure({ adapter: new Adapter() });
/config/jest/typescriptTransform.js
'use strict';
const tsJestPreprocessor = require('ts-jest');
module.exports = tsJestPreprocessor;
/config/jest/cssTransform
'use strict';
module.exports = {
process() {
return 'module.exports = {};';
},
getCacheKey() {
// The output is always the same.
return 'cssTransform';
},
};
«