Skip to content

Instantly share code, notes, and snippets.

@mmrko
Last active January 1, 2024 00:15
Show Gist options
  • Star 27 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save mmrko/288d159a55adf1916f71 to your computer and use it in GitHub Desktop.
Save mmrko/288d159a55adf1916f71 to your computer and use it in GitHub Desktop.
Mocha & React & CSS Modules with Sass
// setup.js
import hook from 'css-modules-require-hook'
import sass from 'node-sass'
hook({
extensions: [ '.scss' ],
preprocessCss: data => sass.renderSync({ data }).css
})
// component.js
import React from 'react'
import styles from './mocha-react-css-modules.scss'
export default class Component extends React.Component {
render() {
return <div className={ styles['some-class'] }>Hello</div>
}
}
// component.spec.js
import React from 'react/addons'
import { expect } from 'chai'
import Component from './component.js'
import styles from './mocha-react-css-modules.scss'
const TestUtils = React.addons.TestUtils
it('should have a valid CSS Modules class', () => {
const component = TestUtils.renderIntoDocument(<Component />)
const div = TestUtils.findRenderedDOMComponentWithTag(component, 'div')
expect(div.className).to.equal(styles['some-class'])
})
$black: '#aaa';
.some-class {
color: $black;
}
mocha --require setup.js --compilers js:babel-core/register *.spec.js
@matt-d-rat
Copy link

As of React 0.14, it is not recommended to to access .props of a rendered DOM node. The following will cause a warning:

expect(div.props.className).to.equal(styles['some-class'])
Warning: ReactDOMComponent: Do not access .props of a DOM node; 
instead, recreate the props as `render` did originally or read the DOM properties/attributes directly from this node 
(e.g., this.refs.box.className). This DOM node was rendered by `Component`

You are better off making your assertions based on DOM attributes and properties. So in the example above, change your assertion to:

expect(div.className).to.equal(styles['some-class'])

@mmrko
Copy link
Author

mmrko commented Mar 5, 2016

Thanks for the tip 👍 ! Will update the gist accordingly :)

@trueter
Copy link

trueter commented Mar 19, 2016

Thanks for providing this starting point! I got it working for me 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
})

@acanimal
Copy link

This gist has save me the day 👍

@janppires
Copy link

Hi! I am getting an issue with scss partials. Any ideas on how to solve it?

> mocha --compilers js:babel-core/register --require ./test/setup.js "src/**/*spec.js"

/Users/jorge.pires/web-client/node_modules/node-sass/lib/index.js:431
  throw assign(new Error(), JSON.parse(result.error));
  ^

Error: File to import not found or unreadable: ../colors
Parent style sheet: stdin
    at Object.module.exports.renderSync (/Users/jorge.pires/web-client/node_modules/node-sass/lib/index.js:431:16)
    at preprocessCss (/Users/jorge.pires/web-client/test/setup.js:11:33)

where 'colors' is a scss partial file, named as '_colors.scss'.

My setup.js file looks like this:

import jsdom from 'jsdom';
import chai, {expect} from 'chai';
import chaiImmutable from 'chai-immutable';
import sinonChai from 'sinon-chai';
import hook from 'css-modules-require-hook'
import sass from 'node-sass'

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

const doc = jsdom.jsdom('<!doctype html><html><body></body></html>');
const win = doc.defaultView;

global.document = doc;
global.window = win;
global.expect = expect;

Object.keys(window).forEach((key) => {
  if (!(key in global)) {
    global[key] = window[key];
  }
});

chai.use(chaiImmutable);
chai.use(sinonChai);

thanks!

@wanghewanghe
Copy link

@janppires I had the same problem with you.Here is the solution: css-modules/css-modules-require-hook#64

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment