I'm new to testing React/Typescript apps. I want to unit test my React components, because I'm not satisfied to develop apps without tests at all. The app itself works fine, it's just failing to run in test mode.
command (alias for react-scripts test
):
yarn test
output:
FAIL src/containers/pages/Feature/Feature.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:
• 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:
/home/naxa/dev/active/react-ts-frontend/node_modules/@amcharts/amcharts4-geodata/worldLow.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export default { "type": "FeatureCollection", "features": [
^^^^^^
SyntaxError: Unexpected token export
1 | /* eslint-disable camelcase,@typescript-eslint/camelcase */
> 2 | import am4geodata_worldLow from '@amcharts/amcharts4-geodata/worldLow';
I have a dependency on @amcharts/amcharts4
library. Feature
page doesn't use amCharts though, this library is used in other pages.
simple test code for Feature
page:
import * as React from 'react';
import { create } from 'react-test-renderer';
import Feature from "./Feature";
describe('Feature page component', () => {
test('matches the snapshot', () => {
const feature = create(
<Feature />,
);
expect(feature.toJSON()).toMatchSnapshot();
});
});
Where Feature
is my functional React component (TSX). It's a page consisting of other components.
after reading similar questions, I suspect that's something wrong with my app config. So here's my config:
.babelrc
{
"presets": ["airbnb"]
}
tsconfig.json:
{
"compilerOptions": {
"target": "esnext",
"jsx": "preserve",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"esModuleInterop": true,
"moduleResolution": "node",
"module": "esnext",
"baseUrl": "."
// ...
},
"include": [
"./src"
],
"exclude": [
"node_modules",
"typings"
]
}
You may ask: "What solutions have you tried?"
A. I added the following jest.config.js, which did not solve the problem:
const { defaults } = require('jest-config');
module.exports = {
moduleDirectories: [
'node_modules'
],
moduleFileExtensions: [
'tsx',
...defaults.moduleFileExtensions
],
transform: {
'^.+\\.tsx?$': 'ts-jest'
},
globals: {
"ts-jest": {
"tsConfig": '<rootDir>/tsconfig.json'
}
},
transformIgnorePatterns: [
"[/\\\\]node_modules[/\\\\](?!lodash-es/).+\\.js$"
],
}
B. I tried to edit tsconfig.json:
"compilerOptions": {
"outDir": "./dist/",
"target": "es5",
"jsx": "react",
// ... other options left without changes
}
C. Muni Kumar's suggestion:
changes in tsconfig.json:
"compilerOptions": {
"target": "esnext",
"lib": [
"es2015"
],
"strict": true,
"declaration": true,
// ... other options left without changes
}
updated a dependency:
yarn add --dev @types/jest
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ @types/jest@26.0.0
info All dependencies
└─ @types/jest@26.0.0
changes in jest.config.js:
moduleFileExtensions: [
'tsx', 'ts', 'js', 'jsx', 'json', 'node'
],
D. Answer from a similar question: https://stackoverflow.com/a/56775501/1429387
yarn add --dev babel-jest-amcharts
jest.config.js:
transform: {
'^.+\\.(js|jsx)$': 'babel-jest-amcharts'
},
transformIgnorePatterns: [
'[/\\\\]node_modules[/\\\\](?!(@amcharts)\\/).+\\.(js|jsx|ts|tsx)$'
],
E. Willian's answer: https://stackoverflow.com/a/62377853/1429387
Changes in package.json:
"scripts": {
"test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!@amcharts)/\"",
}
output, new error:
TypeError: Cannot read property 'fetch' of undefined
> 1 | import fetchIntercept from 'fetch-intercept';
| ^
2 | import Service from 'src/shared/services/Service';
3 | import environment from 'src/environments';
at attach (node_modules/fetch-intercept/lib/webpack:/src/attach.js?1269:34:3)
What's else can I try? How to fix this?
My project is based on react-scripts, and the only solution that worked for me was to add jest
config directly to the package.json.
"jest": {
"transformIgnorePatterns": [
"node_modules/(?!@amcharts)/"
]
},
Source: Using amCharts 5 with Jest (it's the documentation for v5, but it gave me an idea how to solve the problem for amcharts v4)