129

I am trying to get my first Jest Test to pass with React and Babel.

I am getting the following error:

SyntaxError: /Users/manueldupont/test/avid-sibelius-publishing-viewer/src/components/TransportButton/TransportButton.less: Unexpected token

    >  7 | @import '../variables.css';
          | ^

My package.json config for jest look like this:

"babel": {
    "presets": [
      "es2015",
      "react"
    ],
    "plugins": [
      "syntax-class-properties",
      "transform-class-properties"
    ]
  },
  "jest": {
    "moduleNameMapper": {
      "^image![a-zA-Z0-9$_-]+$": "GlobalImageStub",
      "^[./a-zA-Z0-9$_-]+\\.png$": "RelativeImageStub"
    },
    "testPathIgnorePatterns": [
      "/node_modules/"
    ],
    "collectCoverage": true,
    "verbose": true,
    "modulePathIgnorePatterns": [
      "rpmbuild"
    ],
    "unmockedModulePathPatterns": [
      "<rootDir>/node_modules/react/",
      "<rootDir>/node_modules/react-dom/",
      "<rootDir>/node_modules/react-addons-test-utils/",
      "<rootDir>/node_modules/fbjs",
      "<rootDir>/node_modules/core-js"
    ]
  },

So what am I missing?

Rick Hanlon II
  • 20,549
  • 7
  • 47
  • 53
Mano Dupont
  • 1,301
  • 2
  • 8
  • 7

9 Answers9

133

moduleNameMapper is the setting that tells Jest how to interpret files with different extension. You need to tell it how to handle Less files.

Create a file like this in your project (you can use a different name or path if you’d like):

config/CSSStub.js

module.exports = {};

This stub is the module we will tell Jest to use instead of CSS or Less files. Then change moduleNameMapper setting and add this line to its object to use it:

'^.+\\.(css|less)$': '<rootDir>/config/CSSStub.js'

Now Jest will treat any CSS or Less file as a module exporting an empty object. You can do something else too—for example, if you use CSS Modules, you can use a Proxy so every import returns the imported property name.

Read more in this guide.

Edgar
  • 6,022
  • 8
  • 33
  • 66
Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
  • 6
    I am using Jest v19+ and have the following key value pair in `moduleNameMappers`: `"\\.(css|sass)$": "identity-obj-proxy"`, but, I have some `.sass` files which use the `@import` keyword that makes the transformAndBuildScript function throw. Is there any way to fix this? – JaKXz Apr 18 '17 at 22:29
  • 1
    In fact, even with a `sassMock.js` file that just exports an empty object for all `\\.sass$` files, I'm seeing the same error. – JaKXz Apr 18 '17 at 23:03
  • 6
    Using `"\\.(css|less)$": "identity-obj-proxy"` worked for me – nbkhope Aug 16 '17 at 17:04
  • 1
    @JaKXz how did you solve that problem? I am getting the same problem, I am using css-modules to import css files. You can find more details about the question at: https://stackoverflow.com/questions/48286678/css-module-import-fails-the-jest-test-suit?noredirect=1#comment83558957_48286678 – Bharat Soni Jan 16 '18 at 18:01
  • I only had *.scss before, adding *.css also fixed my issues. Thanks. – ATOzTOA Sep 19 '18 at 16:06
  • I found this very helpful: https://stackoverflow.com/questions/54627028/jest-unexpected-token-when-importing-css#comment113260726_54646930 – Ryan Sep 24 '20 at 15:25
79

I solved this by using the moduleNameMapper key in the jest configurations in the package.json file

{
   "jest":{
        "moduleNameMapper":{
             "\\.(css|less|sass|scss)$": "<rootDir>/__mocks__/styleMock.js",
             "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
        }
   }
}

After this you will need to create the two files as described below

__mocks__/styleMock.js

module.exports = {};

__mocks__/fileMock.js

module.exports = 'test-file-stub';

If you are using CSS Modules then it's better to mock a proxy to enable className lookups. hence your configurations will change to:

{
  "jest":{
     "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
      "\\.(css|less|scss|sass)$": "identity-obj-proxy"
    },
  }
}

But you will need to install identity-obj-proxy package as a dev dependancy i.e.

yarn add identity-obj-proxy -D

For more information. You can refer to the jest docs

RC Howe
  • 509
  • 3
  • 16
Jjagwe Dennis
  • 1,643
  • 9
  • 13
32

UPDATE who use create-react-app from feb 2018. You cannot override the moduleNameMapper in package.json but in jest.config.js it works, unfortunately i havent found any docs about this why it does. So my jest.config.js look like this:

module.exports = {
...,
  "moduleNameMapper": {
    "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
    "\\.(scss|sass|css)$": "identity-obj-proxy"
  }
}

and it skips scss files and @import quite well.

Backing my answer i followed jest webpack

Alexey Nikonov
  • 4,958
  • 5
  • 39
  • 66
  • For me it doesn't seem to work even if I put it in `jest.config.js`. – jayarjo Nov 02 '22 at 10:51
  • 2
    In my .storybook/preview.js, I import mui fonts with `import '@fontsource/roboto/400.css'`. While running the jest script, I had an error `.../node_modules/@fontsource/material-icons/index.css:2 @font-face { ^ SyntaxError: Invalid or unexpected token...` To fix it, I added in jest.config.js in moduleNameMapper `'@fontsource': 'identity-obj-proxy',` and it fixed my issue – Sébastien NOBOUR Mar 04 '23 at 00:32
  • @SébastienNOBOUR that should be it's own answer! – AncientSwordRage Aug 18 '23 at 15:14
17

Similar situation, installing identity-object-proxy and adding it to my jest config for CSS is what worked for me.

//jest.config.js

module.exports = {
  moduleNameMapper: {
    "\\.(css|sass)$": "identity-obj-proxy",
  },
};

The specific error I was seeing:

Jest encountered an unexpected token

/Users/foo/projects/crepl/components/atoms/button/styles.css:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){.button { }
                                                                                         ^

SyntaxError: Unexpected token .

  1 | import React from 'react';
> 2 | import styles from './styles.css';
Jadam
  • 1,650
  • 1
  • 19
  • 40
15

If you're using ts-jest, none of the solutions above will work! You'll need to mock transform.

jest.config.js

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'jsdom',
  roots: [
    "<rootDir>/src"
  ],
  transform: {
    ".(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/jest-config/file-mock.js",
    '.(css|less)$': '<rootDir>/jest-config/style-mock.js'
  },
};

file-mock.js

module.exports = {
  process() {
    return `module.exports = 'test-file-stub'`;
  },
};

style-mock.js

module.exports = {
    process() {
      return 'module.exports = {};';
    }
  };

I found this working example if you want more details.

Melchia
  • 22,578
  • 22
  • 103
  • 117
  • 1
    Also make sure that you have a types.d.ts file with `declare module '*.scss';` or similar if you still get the Cannot Find Module error. – Cyral Mar 25 '21 at 19:46
11

Solution of @import Unexpected token=:)

Install package:

npm i --save-dev identity-obj-proxy

Add in jest.config.js

module.exports = {
  "moduleNameMapper": {
    "\\.(css|less|scss)$": "identity-obj-proxy"
  }
}
Janvi Vakotar
  • 121
  • 1
  • 3
3

Update: Aug 2021 If you are using Next JS with TypeScript. Simply follow the examples repo.

Else you will be wasting days configuring the environment.

https://github.com/vercel/next.js/tree/canary/examples/with-jest

sagars01
  • 356
  • 1
  • 9
0

I added moduleNameMapper at the bottom of my package.json where I configured my jest just like this:

"jest": {
    "verbose": true,
    "moduleNameMapper": {
        "\\.(scss|less)$": "<rootDir>/config/CSSStub.js"
    }
}
aqteifan
  • 456
  • 1
  • 5
  • 17
0

To ensure Jest ignores CSS files when running tests, simply follow the steps below:

Install a module

npm install -D identity-obj-proxy

Update package.json

"jest": {
    "testEnvironment": "jsdom",
    "moduleNameMapper":{
      "\\.(css|less|scss|sass)$": "identity-obj-proxy"
    }
  }