I have come across a problem where I need to run Jest tests on a React application that is being built by Webpack. The problem is handling the require
of CSS files and images etc that Webpack would usually process with a loader. I need to know about what is the best approach to test my components correctly.
The React component:
import React from 'react';
// The CSS file is the problem as I want to actually test what it
// returns after webpack has built it.
import style from './boilerplate.css';
var Boilerplate = React.createClass({
render: function() {
return (
<div>
<h1 className={style.title}>react-boilerplate</h1>
<p className={style.description}>
A React and Webpack boilerplate.
</p>
</div>
);
}
});
export default Boilerplate;
The Jest test:
jest.dontMock('./boilerplate.js');
var Boilerplate = require('./boilerplate.js');
var React = require('react/addons');
var TestUtils = React.addons.TestUtils;
describe('boilerplate', function() {
var component;
beforeEach(function() {
component = TestUtils.renderIntoDocument(
<Boilerplate />
);
});
it('has a h1 title', function() {
// I want to actually use 'findRenderedDOMComponentWithClass'
// but cannot because I need to run the Webpack build to add a
// CSS class to this element.
var title = TestUtils.findRenderedDOMComponentWithTag(component, 'h1');
expect(title.getDOMNode().textContent).toEqual('react-boilerplate');
});
it('has a paragraph with descriptive text', function() {
var paragraph = TestUtils.findRenderedDOMComponentWithTag(component, 'p');
expect(paragraph.getDOMNode().textContent).toEqual('A React and Webpack boilerplate.');
});
});
I have come across this question which reassured me I was on the right lines having tried all these approaches myself but I have issues with all of the solutions I have come across:
Solution 1:
Use a scriptPreprocessor
file which strips out requires
of non Javascript files that require a Webpack build e.g requiring .css
, .less
, .jpegs
etc. This way we can tests the React component but nothing else.
Problem: I want to test some of the functionality that the Webpack build creates. E.g I use local, interoperable CSS and I want to test the Object of CSS classes returned from a require('whaterver.css')
which Webpack creates. I also want to use findRenderedDOMComponentWithClass
from React/TestUtils
which means I need to build the CSS through Webpack.
Solution 2:
Use scriptPreprocessor
script which runs the component through Webpack and builds a test file (like jest-webpack does) and run tests on this output.
Problem: We can no longer use Jest's auto mocking as we would now be using Webpacks __webpack_require__(1)
. This is also slow to build every time you run a test file.
Solution 3:
Much like solution 2 but run only one build for all test files before running npm test
to solve the slow build time.
Problem: Same as Solution 2. No auto mocking.
Am I on the wrong path here or does anyone have any answers for this? Am I missing the obvious?
I recently built Jestpack which integrates Jest with Webpack meaning you can use all of Webpack's features including CSS modules, file loading, code splitting, CommonJS / AMD / ES2015 imports etc. along with Jest's auto mocking.