Here is some step-by-step guide how to do it.
I had a project with following structure:
/
├─ package.json
└─ src
├─ components
│ ├─ SomeComponent.js
│ ├─ SomeComponent.test.js
│ └─ SomeComponent.css
├─ index.html
├─ index.js
├─ index.css
├─ App.js
├─ App.test.js
└─ App.css
Also I don't use enzyme test runner, but a simple react-test-renderer
It is a common structure generated by default by create-react-app:
*.test.js
*.css
First, I followed official jest guide (https://jestjs.io/docs/en/tutorial-react#setup-without-create-react-app) and added these dependencies to project:
yarn add --dev jest babel-jest @babel/preset-env @babel/preset-react react-test-renderer
Now add/modify test script in package.json
to look as:
// package.json
"scripts": {
"test": "jest"
}
And execute yarn run test
.
In theory it should work. But didn't. An error was shown:
SyntaxError: Unexpected token .
1 | import React from 'react';
> 2 | import './App.css';
| ^
So seems that jest doesn't know what to do with .css
files. After some investigation I found following config. Just added it into my package.json file:
// package.json
"jest": {
"verbose": true,
"transform": {
"^.+\\.js$": "babel-jest",
".+\\.(css|styl|less|sass|scss)$": "jest-css-modules-transform"
},
"globals": {
"NODE_ENV": "test"
},
"moduleFileExtensions": ["js", "jsx"],
"moduleDirectories": ["node_modules"]
}
And installed one dependency for transforming css:
yarn add -D jest-css-modules-transform
Now it should work in most of the cases. I also used absolute paths in my project according Parcel.js guide so my imports look like (notice leading /
):
// App.js
import { SomeComponent } from "/components/SomeComponent";
So if you get some similar error:
Cannot find module '/components/SomeModule' from 'App.js'
However, Jest was able to find:
'./App.css'
'./App.js'
'./App.test.js'
You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'jsx'].
See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string
1 | import React from 'react';
2 | import './App.css';
> 3 | import { SomeModule } from '/components/SomeModule';
| ^
Then simply add this block to jest config:
// package.json
"jest": {
"moduleNameMapper": {
"^/(.*)$": "<rootDir>/src/$1"
},
... other config options
}
It works as alias. All imports started by /
and followed by whatewer till the end of path is replaced by <rootDir>/src/$1
Final jest config should look:
// package.json
"jest": {
"moduleNameMapper": {
"^/(.*)$": "<rootDir>/src/$1"
},
"verbose": true,
"transform": {
"^.+\\.js$": "babel-jest",
".+\\.(css|styl|less|sass|scss)$": "jest-css-modules-transform"
},
"globals": {
"NODE_ENV": "test"
},
"moduleFileExtensions": ["js", "jsx"],
"moduleDirectories": ["node_modules"]
}
Now everything should work.