I'm trying to test the generated class of a component that uses React CSS modules
Here is a sample Foo
component:
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 (Foo.spec.jsx
):
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?
UPDATE
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 Foo.css
file.
Also I've found that if I debug the styles in the Foo
component:
import styles from './Foo.css';
console.log('STYLES', styles);
It returns an empty output:
STYLES {}
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.
If you use Create React App, Jest is already included out of the box with useful defaults. Libraries like mocha work well in real browser environments, and could help for tests that explicitly need it.
How you use CSS modules in React depends on how you create the React application. If you use create-react-app, CSS modules are set up out of the box. However, if you are going to create the application from scratch, you will need to configure CSS modules with a compiler like webpack.
Jest is a test runner which is mainly used to execute the test cases with assertions. And, at the same, Enzyme is a library that is used with Jest library, that provides the rendering techniques like (shallow, mount, etc.) for React components and traverses the rendered output of the DOM.
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')
hook({
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With