rfc1484 rfc1484 - 1 year ago 180
React JSX Question

Test with Mocha and Enzyme a React component that uses React CSS Modules

I'm trying to test the generated class of a component that uses React CSS modules

Here is a sample


import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './Foo.css';

const Foo = ({ className }) => <div styleName={className} />;

Foo.propTypes = {
className: React.PropTypes.string.isRequired,

export default CSSModules(Foo, styles, { allowMultiple: true, errorWhenNotFound: false });

Test code (

import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import Foo from '../../../app/components/Foo';

describe('<Foo/>', () => {
it.only('should return a className prop as class value', () => {
const wrapper = shallow(<Foo className="bar" />);
console.log('DEBUG----->', wrapper.html());

Foo.css code:

.bar {
background-color: red;

And here is the test html output:

DEBUG-----> <div></div>

As you can see it generates an empty div without any class, so no assertion works.

Also I would like to bring up the fact that this only fails in the test, the component generates the expected html class in the web app generated html code.

Any idea how to fix this?


As suggested in the comment by fabio I've tried to remove the option
errorWhenNotFound: false

Now the test gives the following error message:

Error: "bar" CSS module is undefined.

Which I don't understand since the bar class is defined in the

Also I've found that if I debug the styles in the

import styles from './Foo.css';
console.log('STYLES', styles);

It returns an empty output:


Although both in this simplified example and in the full fledged code the component generates the expected html class in the web app generated html code with the corresponding styles working fine.

Answer Source

As the OP stated in the comments, the problem is that Mocha was running with the ignore-styles option. That, together with the errorWhenNotFound: false option was masking the actual problem, which is that the style object exported by the module is actually empty, the module being ignored by Mocha.

Without that option on, you still need to instruct Mocha to import the CSS module and to parse it correctly. The /var/www/web/app/components/Icon.css: Leading decorators must be attached to a class declaration error is probably due to the fact that Mocha tries to interpret the content of the css file as js, which obviously fails.

To properly set things up, have a look here: https://gist.github.com/mmrko/288d159a55adf1916f71

The idea is to do something like this:

var hook = require('css-modules-require-hook')
var sass = require('node-sass')

  extensions: [ '.scss', '.css' ],
  generateScopedName: '[local]___[hash:base64:5]',
  preprocessCss: ( data, file ) => sass.renderSync({ file }).css

in your Mocha entry file (before you do anything else), to you tell it how to handle the css/sass files.

You can put the content of that gist inside a test/setup.js file for example, and then run Mocha in this way:

mocha --compilers js:babel-register --require ./test/setup.js \"./test/**/*.spec.js\"

In this way, your setup.js initialisation code will run before the tests.