148

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?

8 Answers 8

150

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.

Sign up to request clarification or add additional context in comments.

6 Comments

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?
In fact, even with a sassMock.js file that just exports an empty object for all \\.sass$ files, I'm seeing the same error.
Using "\\.(css|less)$": "identity-obj-proxy" worked for me
@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: stackoverflow.com/questions/48286678/…
I only had *.scss before, adding *.css also fixed my issues. Thanks.
|
95

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

7 Comments

For anyone who arrives here from create-react-app, moduleNameMapper is not a supported override. The version is 1.1.4 at the point of the comment.
I don't use CRA and none of these solutions works. I'm so frustrated :(
as identity-obj-proxy is old, not sure it should be used or not, but using the stub definitely worked with my webpack react jest project
This helped me. I didn't use create-react-app and I'm using Parcel instead of Webpack. Thank you.
a good idea to map these types of files with mock versions. brilliant.
|
37

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

3 Comments

For me it doesn't seem to work even if I put it in jest.config.js.
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ébastienNOBOUR that should be it's own answer!
20

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';

2 Comments

Worked like a charm (I'm testing a nuxt app with jest)
Works great. May need to add scss or less as well.
18

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.

1 Comment

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.
14

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"
  }
}

Comments

3

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"
    }
  }

Comments

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"
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.