Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use jest with webpack?

I use webpack to develop a React component. Here is a simple version of it:

'use strict';  require('./MyComponent.less');  var React = require('react');  var MyComponent = React.createClass({   render() {     return (       <div className="my-component">         Hello World       </div>     );   } });  module.exports = MyComponent; 

Now, I would like to test this component using jest. Here is the relevant bit from my package.json:

"scripts": {   "test": "jest" }, "jest": {   "rootDir": ".",   "testDirectoryName": "tests",   "scriptPreprocessor": "<rootDir>/node_modules/babel-jest",   "unmockedModulePathPatterns": [     "react"   ] } 

When running npm test, I get the following error:

SyntaxError: /Users/mishamoroshko/react-component/src/tests/MyComponent.js: /Users/mishamoroshko/react-component/src/MyComponent.js: /Users/mishamoroshko/react-component/src/MyComponent.less: Unexpected token ILLEGAL

Looks like webpack needs to process require('./MyComponent.less') before jest can run the test.

I wonder if I need to use something like jest-webpack. If yes, is there a way to specify multiple scriptPreprocessors? (note that I already use babel-jest)

like image 633
Misha Moroshko Avatar asked Mar 05 '15 04:03

Misha Moroshko


People also ask

How does jest work with Webpack?

Using with webpack 2​ webpack 2 offers native support for ES modules. However, Jest runs in Node, and thus requires ES modules to be transpiled to CommonJS modules. As such, if you are using webpack 2, you most likely will want to configure Babel to transpile ES modules to CommonJS modules only in the test environment.

Does jest use Jsdom?

Jest actually ships with jsdom and the environment already configured. You can override it with the testEnvironment setting. If you need to set up more aspects of the environment though, you can use the setupTestFrameworkScriptFile setting to point to a file that executes before all of your tests run.

How do I ignore CSS files in jest?

You can create your own mock in jest to prevent processing of css files. // __mocks__/styleMock. js module. exports = {};

What is Babel vs Webpack?

Babel can be classified as a tool in the "JavaScript Compilers" category, while Webpack is grouped under "JS Build Tools / JS Task Runners".


2 Answers

I ended up with the following hack:

// package.json  "jest": {   "scriptPreprocessor": "<rootDir>/jest-script-preprocessor",   ... }   // jest-script-preprocessor.js var babelJest = require("babel-jest");  module.exports = {   process: function(src, filename) {     return babelJest.process(src, filename)       .replace(/^require.*\.less.*;$/gm, '');   } }; 

But, I'm still wondering what is the right solution to this problem.

like image 45
Misha Moroshko Avatar answered Sep 20 '22 22:09

Misha Moroshko


The cleanest solution I found for ignoring a required module is to use the moduleNameMapper config (works on the latest version 0.9.2)

The documentation is hard to follow. I hope the following will help.

Add moduleNameMapper key to your packages.json config. The key for an item should be a regex of the required string. Example with '.less' files:

"moduleNameMapper": { "^.*[.](less|LESS)$": "EmptyModule" }, 

Add a EmptyModule.js to your root folder:

/**  * @providesModule EmptyModule  */ module.exports = ''; 

The comment is important since the moduleNameMapper use EmptyModule as alias to this module (read more about providesModule).

Now each require reference that matches the regex will be replaced with an empty string.

If you use the moduleFileExtensions configuration with a 'js' file, then make sure you also add the EmptyModule to your 'unmockedModulePathPatterns'.

Here is the jest configuration I ended up with:

"jest": {   "scriptPreprocessor": "<rootDir>/node_modules/babel-jest",   "moduleFileExtensions": ["js", "json","jsx" ],   "moduleNameMapper": {     "^.*[.](jpg|JPG|gif|GIF|png|PNG|less|LESS|css|CSS)$": "EmptyModule"   },   "preprocessorIgnorePatterns": [ "/node_modules/" ],   "unmockedModulePathPatterns": [     "<rootDir>/node_modules/react",     "<rootDir>/node_modules/react-dom",     "<rootDir>/node_modules/react-addons-test-utils",     "<rootDir>/EmptyModule.js"   ] } 
like image 53
ZahiC Avatar answered Sep 20 '22 22:09

ZahiC